| // 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. |
| |
| #include "ppapi/proxy/graphics_2d_resource.h" |
| |
| #include "ppapi/c/pp_bool.h" |
| #include "ppapi/c/pp_point.h" |
| #include "ppapi/c/pp_rect.h" |
| #include "ppapi/c/pp_resource.h" |
| #include "ppapi/c/pp_size.h" |
| #include "ppapi/c/ppb_graphics_2d.h" |
| #include "ppapi/proxy/dispatch_reply_message.h" |
| #include "ppapi/proxy/plugin_dispatcher.h" |
| #include "ppapi/proxy/ppapi_messages.h" |
| #include "ppapi/shared_impl/ppapi_globals.h" |
| #include "ppapi/shared_impl/resource_tracker.h" |
| #include "ppapi/shared_impl/tracked_callback.h" |
| #include "ppapi/thunk/enter.h" |
| #include "ppapi/thunk/ppb_image_data_api.h" |
| |
| namespace ppapi { |
| namespace proxy { |
| |
| Graphics2DResource::Graphics2DResource(Connection connection, |
| PP_Instance instance, |
| const PP_Size& size, |
| PP_Bool is_always_opaque) |
| : PluginResource(connection, instance), |
| size_(size), |
| is_always_opaque_(is_always_opaque), |
| scale_(1.0f) { |
| // These checks are copied from PPB_ImageData_Impl::Init to make tests passed. |
| // Let's remove/refactor this when start to refactor ImageData. |
| bool bad_args = |
| size.width <= 0 || size.height <= 0 || |
| static_cast<int64_t>(size.width) * static_cast<int64_t>(size.height) >= |
| std::numeric_limits<int32_t>::max() / 4; |
| if (!bad_args && !sent_create_to_renderer()) { |
| SendCreate(RENDERER, |
| PpapiHostMsg_Graphics2D_Create(size, is_always_opaque)); |
| } |
| } |
| |
| Graphics2DResource::~Graphics2DResource() { |
| } |
| |
| PP_Bool Graphics2DResource::Describe(PP_Size* size, PP_Bool* is_always_opaque) { |
| *size = size_; |
| *is_always_opaque = is_always_opaque_; |
| return PP_TRUE; |
| } |
| |
| thunk::PPB_Graphics2D_API* Graphics2DResource::AsPPB_Graphics2D_API() { |
| return this; |
| } |
| |
| void Graphics2DResource::PaintImageData(PP_Resource image_data, |
| const PP_Point* top_left, |
| const PP_Rect* src_rect) { |
| Resource* image_object = |
| PpapiGlobals::Get()->GetResourceTracker()->GetResource(image_data); |
| if (!image_object || pp_instance() != image_object->pp_instance()) { |
| Log(PP_LOGLEVEL_ERROR, |
| "Graphics2DResource.PaintImageData: Bad image resource."); |
| return; |
| } |
| |
| PP_Rect dummy; |
| memset(&dummy, 0, sizeof(PP_Rect)); |
| Post(RENDERER, PpapiHostMsg_Graphics2D_PaintImageData( |
| image_object->host_resource(), *top_left, |
| !!src_rect, src_rect ? *src_rect : dummy)); |
| } |
| |
| void Graphics2DResource::Scroll(const PP_Rect* clip_rect, |
| const PP_Point* amount) { |
| PP_Rect dummy; |
| memset(&dummy, 0, sizeof(PP_Rect)); |
| Post(RENDERER, PpapiHostMsg_Graphics2D_Scroll( |
| !!clip_rect, clip_rect ? *clip_rect : dummy, *amount)); |
| } |
| |
| void Graphics2DResource::ReplaceContents(PP_Resource image_data) { |
| thunk::EnterResourceNoLock<thunk::PPB_ImageData_API> enter_image( |
| image_data, true); |
| if (enter_image.failed()) |
| return; |
| |
| // Check that the PP_Instance matches. |
| Resource* image_object = |
| PpapiGlobals::Get()->GetResourceTracker()->GetResource(image_data); |
| if (!image_object || pp_instance() != image_object->pp_instance()) { |
| Log(PP_LOGLEVEL_ERROR, |
| "Graphics2DResource.PaintImageData: Bad image resource."); |
| return; |
| } |
| enter_image.object()->SetIsCandidateForReuse(); |
| |
| Post(RENDERER, PpapiHostMsg_Graphics2D_ReplaceContents( |
| image_object->host_resource())); |
| } |
| |
| PP_Bool Graphics2DResource::SetScale(float scale) { |
| if (scale <= 0.0f) |
| return PP_FALSE; |
| Post(RENDERER, PpapiHostMsg_Graphics2D_SetScale(scale)); |
| scale_ = scale; |
| return PP_TRUE; |
| } |
| |
| float Graphics2DResource::GetScale() { |
| return scale_; |
| } |
| |
| PP_Bool Graphics2DResource::SetLayerTransform(float scale, |
| const PP_Point* origin, |
| const PP_Point* translate) { |
| if (scale <= 0.0f) |
| return PP_FALSE; |
| // Adding the origin to the transform. |
| PP_FloatPoint translate_with_origin; |
| translate_with_origin.x = (1 - scale) * origin->x - translate->x; |
| translate_with_origin.y = (1 - scale) * origin->y - translate->y; |
| Post(RENDERER, |
| PpapiHostMsg_Graphics2D_SetLayerTransform(scale, translate_with_origin)); |
| return PP_TRUE; |
| } |
| |
| int32_t Graphics2DResource::Flush(scoped_refptr<TrackedCallback> callback) { |
| // If host is not even created, return failure immediately. This can happen |
| // when failed to initialize (in constructor). |
| if (!sent_create_to_renderer()) |
| return PP_ERROR_FAILED; |
| |
| if (TrackedCallback::IsPending(current_flush_callback_)) |
| return PP_ERROR_INPROGRESS; // Can't have >1 flush pending. |
| current_flush_callback_ = callback; |
| |
| Call<PpapiPluginMsg_Graphics2D_FlushAck>( |
| RENDERER, |
| PpapiHostMsg_Graphics2D_Flush(), |
| base::Bind(&Graphics2DResource::OnPluginMsgFlushACK, this)); |
| return PP_OK_COMPLETIONPENDING; |
| } |
| |
| bool Graphics2DResource::ReadImageData(PP_Resource image, |
| const PP_Point* top_left) { |
| if (!top_left) |
| return false; |
| int32_t result = SyncCall<PpapiPluginMsg_Graphics2D_ReadImageDataAck>( |
| RENDERER, |
| PpapiHostMsg_Graphics2D_ReadImageData(image, *top_left)); |
| return result == PP_OK; |
| } |
| |
| void Graphics2DResource::OnPluginMsgFlushACK( |
| const ResourceMessageReplyParams& params) { |
| current_flush_callback_->Run(params.result()); |
| } |
| |
| } // namespace proxy |
| } // namespace ppapi |