// 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. #ifndef CONTENT_RENDERER_PEPPER_PEPPER_GRAPHICS_2D_HOST_H_ #define CONTENT_RENDERER_PEPPER_PEPPER_GRAPHICS_2D_HOST_H_ #include #include "base/basictypes.h" #include "base/compiler_specific.h" #include "base/memory/weak_ptr.h" #include "content/common/content_export.h" #include "ppapi/c/ppb_graphics_2d.h" #include "ppapi/host/host_message_context.h" #include "ppapi/host/resource_host.h" #include "third_party/WebKit/Source/Platform/chromium/public/WebCanvas.h" #include "webkit/plugins/ppapi/plugin_delegate.h" namespace gfx { class Point; class Rect; } namespace webkit { namespace ppapi { class PPB_ImageData_Impl; class PluginInstance; } // namespace ppapi } // namespace webkit using webkit::ppapi::PPB_ImageData_Impl; namespace content { class RendererPpapiHost; class CONTENT_EXPORT PepperGraphics2DHost : public ppapi::host::ResourceHost, public webkit::ppapi::PluginDelegate::PlatformGraphics2D, public base::SupportsWeakPtr { public: static PepperGraphics2DHost* Create(RendererPpapiHost* host, PP_Instance instance, PP_Resource resource, const PP_Size& size, PP_Bool is_always_opaque); virtual ~PepperGraphics2DHost(); // ppapi::host::ResourceHost override. virtual int32_t OnResourceMessageReceived( const IPC::Message& msg, ppapi::host::HostMessageContext* context) OVERRIDE; // PlatformGraphics2D overrides. virtual bool ReadImageData(PP_Resource image, const PP_Point* top_left) OVERRIDE; virtual bool BindToInstance( webkit::ppapi::PluginInstance* new_instance) OVERRIDE; virtual void Paint(WebKit::WebCanvas* canvas, const gfx::Rect& plugin_rect, const gfx::Rect& paint_rect) OVERRIDE; virtual void ViewWillInitiatePaint() OVERRIDE; virtual void ViewInitiatedPaint() OVERRIDE; virtual void ViewFlushedPaint() OVERRIDE; virtual void SetScale(float scale) OVERRIDE; virtual float GetScale() const OVERRIDE; virtual bool IsAlwaysOpaque() const OVERRIDE; virtual PPB_ImageData_Impl* ImageData() OVERRIDE; virtual bool IsGraphics2DHost() const OVERRIDE; private: PepperGraphics2DHost(RendererPpapiHost* host, PP_Instance instance, PP_Resource resource); bool Init(int width, int height, bool is_always_opaque); int32_t OnHostMsgPaintImageData(ppapi::host::HostMessageContext* context, const ppapi::HostResource& image_data, const PP_Point& top_left, bool src_rect_specified, const PP_Rect& src_rect); int32_t OnHostMsgScroll(ppapi::host::HostMessageContext* context, bool clip_specified, const PP_Rect& clip, const PP_Point& amount); int32_t OnHostMsgReplaceContents(ppapi::host::HostMessageContext* context, const ppapi::HostResource& image_data); int32_t OnHostMsgFlush(ppapi::host::HostMessageContext* context); int32_t OnHostMsgSetScale(ppapi::host::HostMessageContext* context, float scale); int32_t OnHostMsgReadImageData(ppapi::host::HostMessageContext* context, PP_Resource image, const PP_Point& top_left); // If |old_image_data| is not NULL, a previous used ImageData object will be // reused. This is used by ReplaceContents. int32_t Flush(PP_Resource* old_image_data); // Called internally to execute the different queued commands. The // parameters to these functions will have already been validated. The last // rect argument will be filled by each function with the area affected by // the update that requires invalidation. If there were no pixels changed, // this rect can be untouched. void ExecutePaintImageData(PPB_ImageData_Impl* image, int x, int y, const gfx::Rect& src_rect, gfx::Rect* invalidated_rect); void ExecuteScroll(const gfx::Rect& clip, int dx, int dy, gfx::Rect* invalidated_rect); void ExecuteReplaceContents(PPB_ImageData_Impl* image, gfx::Rect* invalidated_rect, PP_Resource* old_image_data); void SendFlushAck(); // Function scheduled to execute by ScheduleOffscreenFlushAck that actually // issues the offscreen callbacks. void SendOffscreenFlushAck(); // Schedules the offscreen flush ACK at a future time. void ScheduleOffscreenFlushAck(); // Returns true if there is any type of flush callback pending. bool HasPendingFlush() const; // Scale |op_rect| to logical pixels, taking care to include partially- // covered logical pixels (aka DIPs). Also scale optional |delta| to logical // pixels as well for scrolling cases. Returns false for scrolling cases where // scaling either |op_rect| or |delta| would require scrolling to fall back to // invalidation due to rounding errors, true otherwise. static bool ConvertToLogicalPixels(float scale, gfx::Rect* op_rect, gfx::Point* delta); RendererPpapiHost* renderer_ppapi_host_; scoped_refptr image_data_; // Non-owning pointer to the plugin instance this context is currently bound // to, if any. If the context is currently unbound, this will be NULL. webkit::ppapi::PluginInstance* bound_instance_; // Keeps track of all drawing commands queued before a Flush call. struct QueuedOperation; typedef std::vector OperationQueue; OperationQueue queued_operations_; // True if we need to send an ACK to plugin. bool need_flush_ack_; // When doing offscreen flushes, we issue a task that issues the callback // later. This is set when one of those tasks is pending so that we can // enforce the "only one pending flush at a time" constraint in the API. bool offscreen_flush_pending_; // Set to true if the plugin declares that this device will always be opaque. // This allows us to do more optimized painting in some cases. bool is_always_opaque_; // Set to the scale between what the plugin considers to be one pixel and one // DIP float scale_; base::WeakPtrFactory weak_ptr_factory_; ppapi::host::ReplyMessageContext flush_reply_context_; bool is_running_in_process_; friend class PepperGraphics2DHostTest; DISALLOW_COPY_AND_ASSIGN(PepperGraphics2DHost); }; } // namespace content #endif // CONTENT_RENDERER_PEPPER_PEPPER_GRAPHICS_2D_HOST_H_