Home | History | Annotate | Download | only in proxy
      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_Dev_SetScale(scale));
    107   scale_ = scale;
    108   return PP_TRUE;
    109 }
    110 
    111 float Graphics2DResource::GetScale() {
    112   return scale_;
    113 }
    114 
    115 void Graphics2DResource::SetOffset(const PP_Point* offset) {
    116   Post(RENDERER, PpapiHostMsg_Graphics2D_SetOffset(*offset));
    117 }
    118 
    119 void Graphics2DResource::SetResizeMode(
    120     PP_Graphics2D_Dev_ResizeMode resize_mode) {
    121   Post(RENDERER, PpapiHostMsg_Graphics2D_SetResizeMode(resize_mode));
    122 }
    123 
    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;
    129 
    130   if (TrackedCallback::IsPending(current_flush_callback_))
    131     return PP_ERROR_INPROGRESS;  // Can't have >1 flush pending.
    132   current_flush_callback_ = callback;
    133 
    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
    136   // Flush was called.
    137   PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(
    138       pp_instance());
    139   ppapi::ViewData view_data;
    140   if (dispatcher) {
    141     InstanceData* data = dispatcher->GetInstanceData(pp_instance());
    142     if (data)
    143       view_data = data->view;
    144   }
    145   Call<PpapiPluginMsg_Graphics2D_FlushAck>(
    146       RENDERER,
    147       PpapiHostMsg_Graphics2D_Flush(view_data),
    148       base::Bind(&Graphics2DResource::OnPluginMsgFlushACK, this));
    149   return PP_OK_COMPLETIONPENDING;
    150 }
    151 
    152 bool Graphics2DResource::ReadImageData(PP_Resource image,
    153                                        const PP_Point* top_left) {
    154   if (!top_left)
    155     return false;
    156   int32_t result = SyncCall<PpapiPluginMsg_Graphics2D_ReadImageDataAck>(
    157       RENDERER,
    158       PpapiHostMsg_Graphics2D_ReadImageData(image, *top_left));
    159   return result == PP_OK;
    160 }
    161 
    162 void Graphics2DResource::OnPluginMsgFlushACK(
    163     const ResourceMessageReplyParams& params) {
    164   current_flush_callback_->Run(params.result());
    165 }
    166 
    167 }  // namespace proxy
    168 }  // namespace ppapi
    169