summaryrefslogtreecommitdiffstats
path: root/ppapi/proxy/graphics_2d_resource.cc
blob: ea8a9c52ce41727c0c61c2f55ebfc807106b5692 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
// 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>(size.width) * static_cast<int64>(size.height) >=
          std::numeric_limits<int32>::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_;
}

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;

  std::vector<ui::LatencyInfo> latency_info;
  PpapiGlobals::Get()->TransferLatencyInfoTo(&latency_info, pp_instance());

  Call<PpapiPluginMsg_Graphics2D_FlushAck>(
      RENDERER,
      PpapiHostMsg_Graphics2D_Flush(latency_info),
      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