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.
5 #include "ppapi/proxy/graphics_2d_resource.h"
7 #include "ppapi/c/pp_bool.h"
8 #include "ppapi/c/pp_point.h"
9 #include "ppapi/c/pp_rect.h"
10 #include "ppapi/c/pp_resource.h"
11 #include "ppapi/c/pp_size.h"
12 #include "ppapi/c/ppb_graphics_2d.h"
13 #include "ppapi/proxy/dispatch_reply_message.h"
14 #include "ppapi/proxy/plugin_dispatcher.h"
15 #include "ppapi/proxy/ppapi_messages.h"
16 #include "ppapi/shared_impl/ppapi_globals.h"
17 #include "ppapi/shared_impl/resource_tracker.h"
18 #include "ppapi/shared_impl/tracked_callback.h"
19 #include "ppapi/thunk/enter.h"
20 #include "ppapi/thunk/ppb_image_data_api.h"
25 Graphics2DResource::Graphics2DResource(Connection connection
,
28 PP_Bool is_always_opaque
)
29 : PluginResource(connection
, instance
),
31 is_always_opaque_(is_always_opaque
),
33 // These checks are copied from PPB_ImageData_Impl::Init to make tests passed.
34 // Let's remove/refactor this when start to refactor ImageData.
35 bool bad_args
= size
.width
<= 0 || size
.height
<= 0 ||
36 static_cast<int64
>(size
.width
) * static_cast<int64
>(size
.height
) >=
37 std::numeric_limits
<int32
>::max() / 4;
38 if (!bad_args
&& !sent_create_to_renderer()) {
40 PpapiHostMsg_Graphics2D_Create(size
, is_always_opaque
));
44 Graphics2DResource::~Graphics2DResource() {
47 PP_Bool
Graphics2DResource::Describe(PP_Size
* size
, PP_Bool
* is_always_opaque
) {
49 *is_always_opaque
= is_always_opaque_
;
53 thunk::PPB_Graphics2D_API
* Graphics2DResource::AsPPB_Graphics2D_API() {
57 void Graphics2DResource::PaintImageData(PP_Resource image_data
,
58 const PP_Point
* top_left
,
59 const PP_Rect
* src_rect
) {
60 Resource
* image_object
=
61 PpapiGlobals::Get()->GetResourceTracker()->GetResource(image_data
);
62 if (!image_object
|| pp_instance() != image_object
->pp_instance()) {
63 Log(PP_LOGLEVEL_ERROR
,
64 "Graphics2DResource.PaintImageData: Bad image resource.");
69 memset(&dummy
, 0, sizeof(PP_Rect
));
70 Post(RENDERER
, PpapiHostMsg_Graphics2D_PaintImageData(
71 image_object
->host_resource(), *top_left
,
72 !!src_rect
, src_rect
? *src_rect
: dummy
));
75 void Graphics2DResource::Scroll(const PP_Rect
* clip_rect
,
76 const PP_Point
* amount
) {
78 memset(&dummy
, 0, sizeof(PP_Rect
));
79 Post(RENDERER
, PpapiHostMsg_Graphics2D_Scroll(
80 !!clip_rect
, clip_rect
? *clip_rect
: dummy
, *amount
));
83 void Graphics2DResource::ReplaceContents(PP_Resource image_data
) {
84 thunk::EnterResourceNoLock
<thunk::PPB_ImageData_API
> enter_image(
86 if (enter_image
.failed())
89 // Check that the PP_Instance matches.
90 Resource
* image_object
=
91 PpapiGlobals::Get()->GetResourceTracker()->GetResource(image_data
);
92 if (!image_object
|| pp_instance() != image_object
->pp_instance()) {
93 Log(PP_LOGLEVEL_ERROR
,
94 "Graphics2DResource.PaintImageData: Bad image resource.");
97 enter_image
.object()->SetIsCandidateForReuse();
99 Post(RENDERER
, PpapiHostMsg_Graphics2D_ReplaceContents(
100 image_object
->host_resource()));
103 PP_Bool
Graphics2DResource::SetScale(float scale
) {
106 Post(RENDERER
, PpapiHostMsg_Graphics2D_Dev_SetScale(scale
));
111 float Graphics2DResource::GetScale() {
115 void Graphics2DResource::SetOffset(const PP_Point
* offset
) {
116 Post(RENDERER
, PpapiHostMsg_Graphics2D_SetOffset(*offset
));
119 void Graphics2DResource::SetResizeMode(
120 PP_Graphics2D_Dev_ResizeMode resize_mode
) {
121 Post(RENDERER
, PpapiHostMsg_Graphics2D_SetResizeMode(resize_mode
));
124 int32_t Graphics2DResource::Flush(scoped_refptr
<TrackedCallback
> callback
) {
125 // If host is not even created, return failure immediately. This can happen
126 // when failed to initialize (in constructor).
127 if (!sent_create_to_renderer())
128 return PP_ERROR_FAILED
;
130 if (TrackedCallback::IsPending(current_flush_callback_
))
131 return PP_ERROR_INPROGRESS
; // Can't have >1 flush pending.
132 current_flush_callback_
= callback
;
134 // Send the current view data with the Flush() message. This allows the
135 // renderer to know what the plugin's view of the renderer is at the time
137 PluginDispatcher
* dispatcher
= PluginDispatcher::GetForInstance(
139 ppapi::ViewData view_data
;
141 InstanceData
* data
= dispatcher
->GetInstanceData(pp_instance());
143 view_data
= data
->view
;
145 Call
<PpapiPluginMsg_Graphics2D_FlushAck
>(
147 PpapiHostMsg_Graphics2D_Flush(view_data
),
148 base::Bind(&Graphics2DResource::OnPluginMsgFlushACK
, this));
149 return PP_OK_COMPLETIONPENDING
;
152 bool Graphics2DResource::ReadImageData(PP_Resource image
,
153 const PP_Point
* top_left
) {
156 int32_t result
= SyncCall
<PpapiPluginMsg_Graphics2D_ReadImageDataAck
>(
158 PpapiHostMsg_Graphics2D_ReadImageData(image
, *top_left
));
159 return result
== PP_OK
;
162 void Graphics2DResource::OnPluginMsgFlushACK(
163 const ResourceMessageReplyParams
& params
) {
164 current_flush_callback_
->Run(params
.result());