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 #include "ppapi/proxy/graphics_2d_resource.h" 6 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" 21 22 namespace ppapi { 23 namespace proxy { 24 25 Graphics2DResource::Graphics2DResource(Connection connection, 26 PP_Instance instance, 27 const PP_Size& size, 28 PP_Bool is_always_opaque) 29 : PluginResource(connection, instance), 30 size_(size), 31 is_always_opaque_(is_always_opaque), 32 scale_(1.0f) { 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()) { 39 SendCreate(RENDERER, 40 PpapiHostMsg_Graphics2D_Create(size, is_always_opaque)); 41 } 42 } 43 44 Graphics2DResource::~Graphics2DResource() { 45 } 46 47 PP_Bool Graphics2DResource::Describe(PP_Size* size, PP_Bool* is_always_opaque) { 48 *size = size_; 49 *is_always_opaque = is_always_opaque_; 50 return PP_TRUE; 51 } 52 53 thunk::PPB_Graphics2D_API* Graphics2DResource::AsPPB_Graphics2D_API() { 54 return this; 55 } 56 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."); 65 return; 66 } 67 68 PP_Rect dummy; 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)); 73 } 74 75 void Graphics2DResource::Scroll(const PP_Rect* clip_rect, 76 const PP_Point* amount) { 77 PP_Rect dummy; 78 memset(&dummy, 0, sizeof(PP_Rect)); 79 Post(RENDERER, PpapiHostMsg_Graphics2D_Scroll( 80 !!clip_rect, clip_rect ? *clip_rect : dummy, *amount)); 81 } 82 83 void Graphics2DResource::ReplaceContents(PP_Resource image_data) { 84 thunk::EnterResourceNoLock<thunk::PPB_ImageData_API> enter_image( 85 image_data, true); 86 if (enter_image.failed()) 87 return; 88 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."); 95 return; 96 } 97 enter_image.object()->SetIsCandidateForReuse(); 98 99 Post(RENDERER, PpapiHostMsg_Graphics2D_ReplaceContents( 100 image_object->host_resource())); 101 } 102 103 PP_Bool Graphics2DResource::SetScale(float scale) { 104 if (scale <= 0.0f) 105 return PP_FALSE; 106 Post(RENDERER, PpapiHostMsg_Graphics2D_SetScale(scale)); 107 scale_ = scale; 108 return PP_TRUE; 109 } 110 111 float Graphics2DResource::GetScale() { 112 return scale_; 113 } 114 115 int32_t Graphics2DResource::Flush(scoped_refptr<TrackedCallback> callback) { 116 // If host is not even created, return failure immediately. This can happen 117 // when failed to initialize (in constructor). 118 if (!sent_create_to_renderer()) 119 return PP_ERROR_FAILED; 120 121 if (TrackedCallback::IsPending(current_flush_callback_)) 122 return PP_ERROR_INPROGRESS; // Can't have >1 flush pending. 123 current_flush_callback_ = callback; 124 125 std::vector<ui::LatencyInfo> latency_info; 126 PpapiGlobals::Get()->TransferLatencyInfoTo(&latency_info, pp_instance()); 127 128 Call<PpapiPluginMsg_Graphics2D_FlushAck>( 129 RENDERER, 130 PpapiHostMsg_Graphics2D_Flush(latency_info), 131 base::Bind(&Graphics2DResource::OnPluginMsgFlushACK, this)); 132 return PP_OK_COMPLETIONPENDING; 133 } 134 135 bool Graphics2DResource::ReadImageData(PP_Resource image, 136 const PP_Point* top_left) { 137 if (!top_left) 138 return false; 139 int32_t result = SyncCall<PpapiPluginMsg_Graphics2D_ReadImageDataAck>( 140 RENDERER, 141 PpapiHostMsg_Graphics2D_ReadImageData(image, *top_left)); 142 return result == PP_OK; 143 } 144 145 void Graphics2DResource::OnPluginMsgFlushACK( 146 const ResourceMessageReplyParams& params) { 147 current_flush_callback_->Run(params.result()); 148 } 149 150 } // namespace proxy 151 } // namespace ppapi 152