1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // This class is an implementation of the ChromotingView for Pepper. It is 6 // callable only on the Pepper thread. 7 8 #ifndef REMOTING_CLIENT_PLUGIN_PEPPER_VIEW_H_ 9 #define REMOTING_CLIENT_PLUGIN_PEPPER_VIEW_H_ 10 11 #include <list> 12 13 #include "base/compiler_specific.h" 14 #include "ppapi/cpp/graphics_2d.h" 15 #include "ppapi/cpp/view.h" 16 #include "ppapi/cpp/point.h" 17 #include "ppapi/utility/completion_callback_factory.h" 18 #include "remoting/client/frame_consumer.h" 19 #include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h" 20 #include "third_party/webrtc/modules/desktop_capture/desktop_region.h" 21 22 namespace base { 23 class Time; 24 } // namespace base 25 26 namespace webrtc { 27 class DesktopFrame; 28 } // namespace webrtc 29 30 namespace remoting { 31 32 class ChromotingInstance; 33 class ClientContext; 34 class FrameProducer; 35 36 class PepperView : public FrameConsumer { 37 public: 38 // Constructs a PepperView for the |instance|. The |instance| and |context| 39 // must outlive this class. 40 PepperView(ChromotingInstance* instance, ClientContext* context); 41 virtual ~PepperView(); 42 43 // Allocates buffers and passes them to the FrameProducer to render into until 44 // the maximum number of buffers are in-flight. 45 void Initialize(FrameProducer* producer); 46 47 // FrameConsumer implementation. 48 virtual void ApplyBuffer(const webrtc::DesktopSize& view_size, 49 const webrtc::DesktopRect& clip_area, 50 webrtc::DesktopFrame* buffer, 51 const webrtc::DesktopRegion& region) OVERRIDE; 52 virtual void ReturnBuffer(webrtc::DesktopFrame* buffer) OVERRIDE; 53 virtual void SetSourceSize(const webrtc::DesktopSize& source_size, 54 const webrtc::DesktopVector& dpi) OVERRIDE; 55 virtual PixelFormat GetPixelFormat() OVERRIDE; 56 57 // Updates the PepperView's size & clipping area, taking into account the 58 // DIP-to-device scale factor. 59 void SetView(const pp::View& view); 60 61 // Returns the dimensions of the most recently displayed frame, in pixels. get_source_size()62 const webrtc::DesktopSize& get_source_size() const { 63 return source_size_; 64 } 65 66 // Return the dimensions of the view in Density Independent Pixels (DIPs). 67 // Note that there may be multiple device pixels per DIP. get_view_size_dips()68 const webrtc::DesktopSize& get_view_size_dips() const { 69 return dips_size_; 70 } 71 72 private: 73 // Allocates a new frame buffer to supply to the FrameProducer to render into. 74 // Returns NULL if the maximum number of buffers has already been allocated. 75 webrtc::DesktopFrame* AllocateBuffer(); 76 77 // Frees a frame buffer previously allocated by AllocateBuffer. 78 void FreeBuffer(webrtc::DesktopFrame* buffer); 79 80 // Renders the parts of |buffer| identified by |region| to the view. If the 81 // clip area of the view has changed since the buffer was generated then 82 // FrameProducer is supplied the missed parts of |region|. The FrameProducer 83 // will be supplied a new buffer when FlushBuffer() completes. 84 void FlushBuffer(const webrtc::DesktopRect& clip_area, 85 webrtc::DesktopFrame* buffer, 86 const webrtc::DesktopRegion& region); 87 88 // Handles completion of FlushBuffer(), triggering a new buffer to be 89 // returned to FrameProducer for rendering. 90 void OnFlushDone(int result, 91 const base::Time& paint_start, 92 webrtc::DesktopFrame* buffer); 93 94 // Reference to the creating plugin instance. Needed for interacting with 95 // pepper. Marking explicitly as const since it must be initialized at 96 // object creation, and never change. 97 ChromotingInstance* const instance_; 98 99 // Context should be constant for the lifetime of the plugin. 100 ClientContext* const context_; 101 102 pp::Graphics2D graphics2d_; 103 104 FrameProducer* producer_; 105 106 // List of allocated image buffers. 107 std::list<webrtc::DesktopFrame*> buffers_; 108 109 // Queued buffer to paint, with clip area and dirty region in device pixels. 110 webrtc::DesktopFrame* merge_buffer_; 111 webrtc::DesktopRect merge_clip_area_; 112 webrtc::DesktopRegion merge_region_; 113 114 // View size in Density Independent Pixels (DIPs). 115 webrtc::DesktopSize dips_size_; 116 117 // Scale factor from DIPs to device pixels. 118 float dips_to_device_scale_; 119 120 // View size in output pixels. This is the size at which FrameProducer must 121 // render frames. It usually matches the DIPs size of the view, but may match 122 // the size in device pixels when scaling is in effect, to reduce artefacts. 123 webrtc::DesktopSize view_size_; 124 125 // Scale factor from output pixels to device pixels. 126 float dips_to_view_scale_; 127 128 // Visible area of the view, in output pixels. 129 webrtc::DesktopRect clip_area_; 130 131 // Size of the most recent source frame in pixels. 132 webrtc::DesktopSize source_size_; 133 134 // Resolution of the most recent source frame dots-per-inch. 135 webrtc::DesktopVector source_dpi_; 136 137 // True if there is already a Flush() pending on the Graphics2D context. 138 bool flush_pending_; 139 140 // True after Initialize() has been called, until TearDown(). 141 bool is_initialized_; 142 143 // True after the first call to ApplyBuffer(). 144 bool frame_received_; 145 146 pp::CompletionCallbackFactory<PepperView> callback_factory_; 147 148 DISALLOW_COPY_AND_ASSIGN(PepperView); 149 }; 150 151 } // namespace remoting 152 153 #endif // REMOTING_CLIENT_PLUGIN_PEPPER_VIEW_H_ 154