// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // This class is an implementation of the ChromotingView for Pepper. It is // callable only on the Pepper thread. #ifndef REMOTING_CLIENT_PLUGIN_PEPPER_VIEW_H_ #define REMOTING_CLIENT_PLUGIN_PEPPER_VIEW_H_ #include <list> #include "base/compiler_specific.h" #include "ppapi/cpp/graphics_2d.h" #include "ppapi/cpp/view.h" #include "ppapi/cpp/point.h" #include "ppapi/utility/completion_callback_factory.h" #include "remoting/client/frame_consumer.h" #include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h" #include "third_party/webrtc/modules/desktop_capture/desktop_region.h" namespace base { class Time; } // namespace base namespace webrtc { class DesktopFrame; } // namespace webrtc namespace remoting { class ChromotingInstance; class ClientContext; class FrameProducer; class PepperView : public FrameConsumer { public: // Constructs a PepperView for the |instance|. The |instance| and |context| // must outlive this class. PepperView(ChromotingInstance* instance, ClientContext* context); virtual ~PepperView(); // Allocates buffers and passes them to the FrameProducer to render into until // the maximum number of buffers are in-flight. void Initialize(FrameProducer* producer); // FrameConsumer implementation. virtual void ApplyBuffer(const webrtc::DesktopSize& view_size, const webrtc::DesktopRect& clip_area, webrtc::DesktopFrame* buffer, const webrtc::DesktopRegion& region) OVERRIDE; virtual void ReturnBuffer(webrtc::DesktopFrame* buffer) OVERRIDE; virtual void SetSourceSize(const webrtc::DesktopSize& source_size, const webrtc::DesktopVector& dpi) OVERRIDE; virtual PixelFormat GetPixelFormat() OVERRIDE; // Updates the PepperView's size & clipping area, taking into account the // DIP-to-device scale factor. void SetView(const pp::View& view); // Returns the dimensions of the most recently displayed frame, in pixels. const webrtc::DesktopSize& get_source_size() const { return source_size_; } // Return the dimensions of the view in Density Independent Pixels (DIPs). // Note that there may be multiple device pixels per DIP. const webrtc::DesktopSize& get_view_size_dips() const { return dips_size_; } private: // Allocates a new frame buffer to supply to the FrameProducer to render into. // Returns NULL if the maximum number of buffers has already been allocated. webrtc::DesktopFrame* AllocateBuffer(); // Frees a frame buffer previously allocated by AllocateBuffer. void FreeBuffer(webrtc::DesktopFrame* buffer); // Renders the parts of |buffer| identified by |region| to the view. If the // clip area of the view has changed since the buffer was generated then // FrameProducer is supplied the missed parts of |region|. The FrameProducer // will be supplied a new buffer when FlushBuffer() completes. void FlushBuffer(const webrtc::DesktopRect& clip_area, webrtc::DesktopFrame* buffer, const webrtc::DesktopRegion& region); // Handles completion of FlushBuffer(), triggering a new buffer to be // returned to FrameProducer for rendering. void OnFlushDone(int result, const base::Time& paint_start, webrtc::DesktopFrame* buffer); // Reference to the creating plugin instance. Needed for interacting with // pepper. Marking explicitly as const since it must be initialized at // object creation, and never change. ChromotingInstance* const instance_; // Context should be constant for the lifetime of the plugin. ClientContext* const context_; pp::Graphics2D graphics2d_; FrameProducer* producer_; // List of allocated image buffers. std::list<webrtc::DesktopFrame*> buffers_; // Queued buffer to paint, with clip area and dirty region in device pixels. webrtc::DesktopFrame* merge_buffer_; webrtc::DesktopRect merge_clip_area_; webrtc::DesktopRegion merge_region_; // View size in Density Independent Pixels (DIPs). webrtc::DesktopSize dips_size_; // Scale factor from DIPs to device pixels. float dips_to_device_scale_; // View size in output pixels. This is the size at which FrameProducer must // render frames. It usually matches the DIPs size of the view, but may match // the size in device pixels when scaling is in effect, to reduce artefacts. webrtc::DesktopSize view_size_; // Scale factor from output pixels to device pixels. float dips_to_view_scale_; // Visible area of the view, in output pixels. webrtc::DesktopRect clip_area_; // Size of the most recent source frame in pixels. webrtc::DesktopSize source_size_; // Resolution of the most recent source frame dots-per-inch. webrtc::DesktopVector source_dpi_; // True if there is already a Flush() pending on the Graphics2D context. bool flush_pending_; // True after Initialize() has been called, until TearDown(). bool is_initialized_; // True after the first call to ApplyBuffer(). bool frame_received_; pp::CompletionCallbackFactory<PepperView> callback_factory_; DISALLOW_COPY_AND_ASSIGN(PepperView); }; } // namespace remoting #endif // REMOTING_CLIENT_PLUGIN_PEPPER_VIEW_H_