12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/proxy/graphics_2d_resource.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/c/pp_bool.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/c/pp_point.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/c/pp_rect.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/c/pp_resource.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/c/pp_size.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/c/ppb_graphics_2d.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/proxy/dispatch_reply_message.h"
14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ppapi/proxy/plugin_dispatcher.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/proxy/ppapi_messages.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/shared_impl/ppapi_globals.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/shared_impl/resource_tracker.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/shared_impl/tracked_callback.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/thunk/enter.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/thunk/ppb_image_data_api.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace ppapi {
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace proxy {
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Graphics2DResource::Graphics2DResource(Connection connection,
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                       PP_Instance instance,
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                       const PP_Size& size,
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                       PP_Bool is_always_opaque)
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : PluginResource(connection, instance),
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      size_(size),
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      is_always_opaque_(is_always_opaque),
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      scale_(1.0f) {
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // These checks are copied from PPB_ImageData_Impl::Init to make tests passed.
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Let's remove/refactor this when start to refactor ImageData.
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool bad_args = size.width <= 0 || size.height <= 0 ||
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      static_cast<int64>(size.width) * static_cast<int64>(size.height) >=
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          std::numeric_limits<int32>::max() / 4;
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!bad_args && !sent_create_to_renderer()) {
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SendCreate(RENDERER,
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        PpapiHostMsg_Graphics2D_Create(size, is_always_opaque));
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Graphics2DResource::~Graphics2DResource() {
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PP_Bool Graphics2DResource::Describe(PP_Size* size, PP_Bool* is_always_opaque) {
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *size = size_;
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *is_always_opaque = is_always_opaque_;
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return PP_TRUE;
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)thunk::PPB_Graphics2D_API* Graphics2DResource::AsPPB_Graphics2D_API() {
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return this;
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Graphics2DResource::PaintImageData(PP_Resource image_data,
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        const PP_Point* top_left,
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        const PP_Rect* src_rect) {
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Resource* image_object =
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      PpapiGlobals::Get()->GetResourceTracker()->GetResource(image_data);
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!image_object || pp_instance() != image_object->pp_instance()) {
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Log(PP_LOGLEVEL_ERROR,
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        "Graphics2DResource.PaintImageData: Bad image resource.");
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PP_Rect dummy;
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  memset(&dummy, 0, sizeof(PP_Rect));
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Post(RENDERER, PpapiHostMsg_Graphics2D_PaintImageData(
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      image_object->host_resource(), *top_left,
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !!src_rect, src_rect ? *src_rect : dummy));
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Graphics2DResource::Scroll(const PP_Rect* clip_rect,
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                const PP_Point* amount) {
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PP_Rect dummy;
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  memset(&dummy, 0, sizeof(PP_Rect));
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Post(RENDERER, PpapiHostMsg_Graphics2D_Scroll(
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !!clip_rect, clip_rect ? *clip_rect : dummy, *amount));
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Graphics2DResource::ReplaceContents(PP_Resource image_data) {
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  thunk::EnterResourceNoLock<thunk::PPB_ImageData_API> enter_image(
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      image_data, true);
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (enter_image.failed())
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Check that the PP_Instance matches.
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Resource* image_object =
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      PpapiGlobals::Get()->GetResourceTracker()->GetResource(image_data);
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!image_object || pp_instance() != image_object->pp_instance()) {
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Log(PP_LOGLEVEL_ERROR,
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        "Graphics2DResource.PaintImageData: Bad image resource.");
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  enter_image.object()->SetIsCandidateForReuse();
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Post(RENDERER, PpapiHostMsg_Graphics2D_ReplaceContents(
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      image_object->host_resource()));
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)PP_Bool Graphics2DResource::SetScale(float scale) {
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (scale <= 0.0f)
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return PP_FALSE;
106e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  Post(RENDERER, PpapiHostMsg_Graphics2D_SetScale(scale));
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scale_ = scale;
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return PP_TRUE;
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)float Graphics2DResource::GetScale() {
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return scale_;
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)int32_t Graphics2DResource::Flush(scoped_refptr<TrackedCallback> callback) {
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If host is not even created, return failure immediately.  This can happen
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // when failed to initialize (in constructor).
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!sent_create_to_renderer())
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return PP_ERROR_FAILED;
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (TrackedCallback::IsPending(current_flush_callback_))
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return PP_ERROR_INPROGRESS;  // Can't have >1 flush pending.
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_flush_callback_ = callback;
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::vector<ui::LatencyInfo> latency_info;
126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PpapiGlobals::Get()->TransferLatencyInfoTo(&latency_info, pp_instance());
127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Call<PpapiPluginMsg_Graphics2D_FlushAck>(
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      RENDERER,
130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      PpapiHostMsg_Graphics2D_Flush(latency_info),
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&Graphics2DResource::OnPluginMsgFlushACK, this));
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return PP_OK_COMPLETIONPENDING;
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool Graphics2DResource::ReadImageData(PP_Resource image,
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                       const PP_Point* top_left) {
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!top_left)
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int32_t result = SyncCall<PpapiPluginMsg_Graphics2D_ReadImageDataAck>(
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      RENDERER,
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      PpapiHostMsg_Graphics2D_ReadImageData(image, *top_left));
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return result == PP_OK;
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Graphics2DResource::OnPluginMsgFlushACK(
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const ResourceMessageReplyParams& params) {
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_flush_callback_->Run(params.result());
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace proxy
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace ppapi
152