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 #ifndef CONTENT_RENDERER_PEPPER_PEPPER_GRAPHICS_2D_HOST_H_ 6 #define CONTENT_RENDERER_PEPPER_PEPPER_GRAPHICS_2D_HOST_H_ 7 8 #include <vector> 9 10 #include "base/basictypes.h" 11 #include "base/compiler_specific.h" 12 #include "base/memory/weak_ptr.h" 13 #include "content/common/content_export.h" 14 #include "ppapi/c/ppb_graphics_2d.h" 15 #include "ppapi/host/host_message_context.h" 16 #include "ppapi/host/resource_host.h" 17 #include "third_party/WebKit/public/platform/WebCanvas.h" 18 19 namespace gfx { 20 class Point; 21 class Rect; 22 } 23 24 namespace content { 25 26 class PepperPluginInstanceImpl; 27 class PPB_ImageData_Impl; 28 class RendererPpapiHost; 29 30 class CONTENT_EXPORT PepperGraphics2DHost 31 : public ppapi::host::ResourceHost, 32 public base::SupportsWeakPtr<PepperGraphics2DHost> { 33 public: 34 static PepperGraphics2DHost* Create(RendererPpapiHost* host, 35 PP_Instance instance, 36 PP_Resource resource, 37 const PP_Size& size, 38 PP_Bool is_always_opaque); 39 40 virtual ~PepperGraphics2DHost(); 41 42 // ppapi::host::ResourceHost override. 43 virtual int32_t OnResourceMessageReceived( 44 const IPC::Message& msg, 45 ppapi::host::HostMessageContext* context) OVERRIDE; 46 virtual bool IsGraphics2DHost() OVERRIDE; 47 48 bool ReadImageData(PP_Resource image, 49 const PP_Point* top_left); 50 // Assciates this device with the given plugin instance. You can pass NULL 51 // to clear the existing device. Returns true on success. In this case, a 52 // repaint of the page will also be scheduled. Failure means that the device 53 // is already bound to a different instance, and nothing will happen. 54 bool BindToInstance(PepperPluginInstanceImpl* new_instance); 55 // Paints the current backing store to the web page. 56 void Paint(WebKit::WebCanvas* canvas, 57 const gfx::Rect& plugin_rect, 58 const gfx::Rect& paint_rect); 59 60 // Notifications about the view's progress painting. See PluginInstance. 61 // These messages are used to send Flush callbacks to the plugin. 62 void ViewWillInitiatePaint(); 63 void ViewInitiatedPaint(); 64 void ViewFlushedPaint(); 65 66 void SetScale(float scale); 67 float GetScale() const; 68 bool IsAlwaysOpaque() const; 69 PPB_ImageData_Impl* ImageData(); 70 71 private: 72 PepperGraphics2DHost(RendererPpapiHost* host, 73 PP_Instance instance, 74 PP_Resource resource); 75 76 bool Init(int width, int height, bool is_always_opaque); 77 78 int32_t OnHostMsgPaintImageData(ppapi::host::HostMessageContext* context, 79 const ppapi::HostResource& image_data, 80 const PP_Point& top_left, 81 bool src_rect_specified, 82 const PP_Rect& src_rect); 83 int32_t OnHostMsgScroll(ppapi::host::HostMessageContext* context, 84 bool clip_specified, 85 const PP_Rect& clip, 86 const PP_Point& amount); 87 int32_t OnHostMsgReplaceContents(ppapi::host::HostMessageContext* context, 88 const ppapi::HostResource& image_data); 89 int32_t OnHostMsgFlush(ppapi::host::HostMessageContext* context); 90 int32_t OnHostMsgSetScale(ppapi::host::HostMessageContext* context, 91 float scale); 92 int32_t OnHostMsgReadImageData(ppapi::host::HostMessageContext* context, 93 PP_Resource image, 94 const PP_Point& top_left); 95 96 // If |old_image_data| is not NULL, a previous used ImageData object will be 97 // reused. This is used by ReplaceContents. 98 int32_t Flush(PP_Resource* old_image_data); 99 100 // Called internally to execute the different queued commands. The 101 // parameters to these functions will have already been validated. The last 102 // rect argument will be filled by each function with the area affected by 103 // the update that requires invalidation. If there were no pixels changed, 104 // this rect can be untouched. 105 void ExecutePaintImageData(PPB_ImageData_Impl* image, 106 int x, int y, 107 const gfx::Rect& src_rect, 108 gfx::Rect* invalidated_rect); 109 void ExecuteScroll(const gfx::Rect& clip, int dx, int dy, 110 gfx::Rect* invalidated_rect); 111 void ExecuteReplaceContents(PPB_ImageData_Impl* image, 112 gfx::Rect* invalidated_rect, 113 PP_Resource* old_image_data); 114 115 void SendFlushAck(); 116 117 // Function scheduled to execute by ScheduleOffscreenFlushAck that actually 118 // issues the offscreen callbacks. 119 void SendOffscreenFlushAck(); 120 121 // Schedules the offscreen flush ACK at a future time. 122 void ScheduleOffscreenFlushAck(); 123 124 // Returns true if there is any type of flush callback pending. 125 bool HasPendingFlush() const; 126 127 // Scale |op_rect| to logical pixels, taking care to include partially- 128 // covered logical pixels (aka DIPs). Also scale optional |delta| to logical 129 // pixels as well for scrolling cases. Returns false for scrolling cases where 130 // scaling either |op_rect| or |delta| would require scrolling to fall back to 131 // invalidation due to rounding errors, true otherwise. 132 static bool ConvertToLogicalPixels(float scale, 133 gfx::Rect* op_rect, 134 gfx::Point* delta); 135 136 137 RendererPpapiHost* renderer_ppapi_host_; 138 139 scoped_refptr<PPB_ImageData_Impl> image_data_; 140 141 // Non-owning pointer to the plugin instance this context is currently bound 142 // to, if any. If the context is currently unbound, this will be NULL. 143 PepperPluginInstanceImpl* bound_instance_; 144 145 // Keeps track of all drawing commands queued before a Flush call. 146 struct QueuedOperation; 147 typedef std::vector<QueuedOperation> OperationQueue; 148 OperationQueue queued_operations_; 149 150 // True if we need to send an ACK to plugin. 151 bool need_flush_ack_; 152 153 // When doing offscreen flushes, we issue a task that issues the callback 154 // later. This is set when one of those tasks is pending so that we can 155 // enforce the "only one pending flush at a time" constraint in the API. 156 bool offscreen_flush_pending_; 157 158 // Set to true if the plugin declares that this device will always be opaque. 159 // This allows us to do more optimized painting in some cases. 160 bool is_always_opaque_; 161 162 // Set to the scale between what the plugin considers to be one pixel and one 163 // DIP 164 float scale_; 165 166 base::WeakPtrFactory<PepperGraphics2DHost> weak_ptr_factory_; 167 168 ppapi::host::ReplyMessageContext flush_reply_context_; 169 170 bool is_running_in_process_; 171 172 friend class PepperGraphics2DHostTest; 173 DISALLOW_COPY_AND_ASSIGN(PepperGraphics2DHost); 174 }; 175 176 } // namespace content 177 178 #endif // CONTENT_RENDERER_PEPPER_PEPPER_GRAPHICS_2D_HOST_H_ 179