Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(90)

Side by Side Diff: ppapi/proxy/compositor_layer_resource.cc

Issue 298023004: [PPAPI] Compositor API implementation (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@compositor_api_def_new
Patch Set: Fix review issues and rebase Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ppapi/proxy/compositor_layer_resource.h ('k') | ppapi/proxy/compositor_resource.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ppapi/proxy/compositor_layer_resource.h" 5 #include "ppapi/proxy/compositor_layer_resource.h"
6 6
7 #include "base/logging.h"
8 #include "gpu/command_buffer/client/gles2_implementation.h"
9 #include "gpu/command_buffer/common/mailbox.h"
10 #include "ppapi/proxy/compositor_resource.h"
11 #include "ppapi/shared_impl/ppb_graphics_3d_shared.h"
12 #include "ppapi/thunk/enter.h"
13 #include "ppapi/thunk/ppb_graphics_3d_api.h"
14 #include "ppapi/thunk/ppb_image_data_api.h"
15
16 using gpu::gles2::GLES2Implementation;
17 using ppapi::thunk::EnterResourceNoLock;
18 using ppapi::thunk::PPB_ImageData_API;
19 using ppapi::thunk::PPB_Graphics3D_API;
20
7 namespace ppapi { 21 namespace ppapi {
8 namespace proxy { 22 namespace proxy {
9 23
10 CompositorLayerResource::CompositorLayerResource(Connection connection, 24 namespace {
11 PP_Instance instance) 25
12 : PluginResource(connection, instance) { 26 class Scoped2DTextureBinder {
27 public:
28 Scoped2DTextureBinder(GLES2Implementation* gl, uint32_t id)
29 : gl_(gl), old_id_(-1) {
30 gl_->GetIntegerv(GL_TEXTURE_BINDING_2D, &old_id_);
31 gl_->BindTexture(GL_TEXTURE_2D, id);
32 }
33
34 ~Scoped2DTextureBinder() {
35 gl_->BindTexture(GL_TEXTURE_2D, old_id_);
36 }
37
38 private:
39 GLES2Implementation* gl_;
40 int32_t old_id_;
41 };
42
43 float clamp(float value) {
44 return std::min(std::max(value, 0.0f), 1.0f);
45 }
46
47 void OnTextureReleased(
48 const ScopedPPResource& layer,
49 const ScopedPPResource& context,
50 uint32_t texture,
51 const scoped_refptr<TrackedCallback>& release_callback,
52 uint32_t sync_point,
53 bool is_lost) {
54 if (!TrackedCallback::IsPending(release_callback))
55 return;
56
57 do {
58 if (!sync_point)
59 break;
60
61 EnterResourceNoLock<PPB_Graphics3D_API> enter(context.get(), true);
62 if (enter.failed())
63 break;
64
65 PPB_Graphics3D_Shared* graphics =
66 static_cast<PPB_Graphics3D_Shared*>(enter.object());
67
68 GLES2Implementation* gl = graphics->gles2_impl();
69 gl->WaitSyncPointCHROMIUM(sync_point);
70 } while (false);
71
72 release_callback->Run(is_lost ? PP_ERROR_FAILED : PP_OK);
73 }
74
75 void OnImageReleased(
76 const ScopedPPResource& layer,
77 const ScopedPPResource& image,
78 const scoped_refptr<TrackedCallback>& release_callback,
79 uint32_t sync_point,
80 bool is_lost) {
81 if (!TrackedCallback::IsPending(release_callback))
82 return;
83 release_callback->Run(PP_OK);
84 }
85
86 } // namespace
87
88 CompositorLayerResource::CompositorLayerResource(
89 Connection connection,
90 PP_Instance instance,
91 const CompositorResource* compositor)
92 : PluginResource(connection, instance),
93 compositor_(compositor),
94 source_size_(PP_MakeFloatSize(0.0f, 0.0f)) {
13 } 95 }
14 96
15 CompositorLayerResource::~CompositorLayerResource() { 97 CompositorLayerResource::~CompositorLayerResource() {
98 DCHECK(!compositor_);
99 DCHECK(release_callback_.is_null());
16 } 100 }
17 101
18 thunk::PPB_CompositorLayer_API* 102 thunk::PPB_CompositorLayer_API*
19 CompositorLayerResource::AsPPB_CompositorLayer_API() { 103 CompositorLayerResource::AsPPB_CompositorLayer_API() {
20 return this; 104 return this;
21 } 105 }
22 106
23 int32_t CompositorLayerResource::SetColor(float red, 107 int32_t CompositorLayerResource::SetColor(float red,
24 float green, 108 float green,
25 float blue, 109 float blue,
26 float alpha, 110 float alpha,
27 const PP_Size* size) { 111 const PP_Size* size) {
28 return PP_ERROR_NOTSUPPORTED; 112 if (!compositor_)
113 return PP_ERROR_BADRESOURCE;
114
115 if (compositor_->IsInProgress())
116 return PP_ERROR_INPROGRESS;
117
118 if (!SetType(CompositorLayerData::TYPE_COLOR))
119 return PP_ERROR_BADARGUMENT;
120
121 if (!size)
122 return PP_ERROR_BADARGUMENT;
123
124 data_.color.red = clamp(red);
125 data_.color.green = clamp(green);
126 data_.color.blue = clamp(blue);
127 data_.color.alpha = clamp(alpha);
128 data_.size = *size;
129
130 return PP_OK;
29 } 131 }
30 132
31 int32_t CompositorLayerResource::SetTexture( 133 int32_t CompositorLayerResource::SetTexture(
32 PP_Resource context, 134 PP_Resource context,
33 uint32_t texture, 135 uint32_t texture,
34 const PP_Size* size, 136 const PP_Size* size,
35 const scoped_refptr<ppapi::TrackedCallback>& callback) { 137 const scoped_refptr<TrackedCallback>& release_callback) {
36 return PP_ERROR_NOTSUPPORTED; 138 int32_t rv = CheckForSetTextureAndImage(
139 CompositorLayerData::TYPE_TEXTURE, release_callback);
140 if (rv != PP_OK)
141 return rv;
142
143 EnterResourceNoLock<PPB_Graphics3D_API> enter(context, true);
144 if (enter.failed())
145 return PP_ERROR_BADRESOURCE;
146
147 if (!size || size->width <= 0 || size->height <= 0)
148 return PP_ERROR_BADARGUMENT;
149
150 PPB_Graphics3D_Shared* graphics =
151 static_cast<PPB_Graphics3D_Shared*>(enter.object());
152
153 GLES2Implementation* gl = graphics->gles2_impl();
154 Scoped2DTextureBinder scoped_2d_texture_binder(gl, texture);
155
156 // Generate a Mailbox for the texture.
157 gl->GenMailboxCHROMIUM(data_.texture.mailbox);
158 gl->ProduceTextureCHROMIUM(GL_TEXTURE_2D, data_.texture.mailbox);
159
160 // Set the source size to (1, 1). It will be used to verify the source_rect
161 // passed to SetSourceRect().
162 source_size_ = PP_MakeFloatSize(1.0f, 1.0f);
163
164 data_.resource_id = compositor_->GenerateResourceId();
165 data_.texture.sync_point = gl->InsertSyncPointCHROMIUM();
166 data_.size = *size;
167 data_.texture.source_rect.point = PP_MakeFloatPoint(0.0f, 0.0f);
168 data_.texture.source_rect.size = source_size_;
169
170 release_callback_ = base::Bind(
171 &OnTextureReleased,
172 ScopedPPResource(pp_resource()), // Keep layer alive.
173 ScopedPPResource(context), // Keep context alive
174 texture,
175 release_callback);
176
177 return PP_OK_COMPLETIONPENDING;
37 } 178 }
38 179
39 int32_t CompositorLayerResource::SetImage( 180 int32_t CompositorLayerResource::SetImage(
40 PP_Resource image_data, 181 PP_Resource image_data,
41 const PP_Size* size, 182 const PP_Size* size,
42 const scoped_refptr<ppapi::TrackedCallback>& callback) { 183 const scoped_refptr<TrackedCallback>& release_callback) {
43 return PP_ERROR_NOTSUPPORTED; 184 int32_t rv = CheckForSetTextureAndImage(
185 CompositorLayerData::TYPE_IMAGE, release_callback);
186 if (rv != PP_OK)
187 return rv;
188
189 EnterResourceNoLock<PPB_ImageData_API> enter(image_data, true);
190 if (enter.failed())
191 return PP_ERROR_BADRESOURCE;
192
193 PP_ImageDataDesc desc;
194 if (!enter.object()->Describe(&desc))
195 return PP_ERROR_BADARGUMENT;
196
197 // TODO(penghuang): Support image which width * 4 != stride.
198 if (desc.size.width * 4 != desc.stride)
199 return PP_ERROR_BADARGUMENT;
200
201 // TODO(penghuang): Support all formats.
202 if (desc.format != PP_IMAGEDATAFORMAT_RGBA_PREMUL)
203 return PP_ERROR_BADARGUMENT;
204
205 if (!size || size->width <= 0 || size->height <= 0)
206 return PP_ERROR_BADARGUMENT;
207
208 // Set the source size to image's size. It will be used to verify
209 // the source_rect passed to SetSourceRect().
210 source_size_ = PP_MakeFloatSize(desc.size.width, desc.size.height);
211
212 data_.size = size ? *size : desc.size;
213 data_.resource_id = compositor_->GenerateResourceId();
214 data_.image.instance = enter.resource()->host_resource().instance();
215 data_.image.host_resource = enter.resource()->host_resource().host_resource();
216 data_.image.source_rect.point = PP_MakeFloatPoint(0.0f, 0.0f);
217 data_.image.source_rect.size = source_size_;
218
219 release_callback_ = base::Bind(
220 &OnImageReleased,
221 ScopedPPResource(pp_resource()), // Keep layer alive.
raymes 2014/06/10 05:00:37 Why do we need to keep the layer resource alive?
Peng 2014/06/10 11:44:22 Because any completion callback will be called wit
raymes 2014/06/11 00:21:06 But isn't it ok for the release callback to be cal
Peng 2014/06/11 01:43:11 Even if the CompositorLayerResource has been relea
raymes 2014/06/12 02:31:25 Ok that seems reasonable. Could you please add a c
Peng 2014/06/12 14:24:36 Done.
222 ScopedPPResource(image_data), // Keep image_data alive.
223 release_callback);
224
225 return PP_OK_COMPLETIONPENDING;
44 } 226 }
45 227
46 int32_t CompositorLayerResource::SetClipRect(const PP_Rect* rect) { 228 int32_t CompositorLayerResource::SetClipRect(const PP_Rect* rect) {
47 return PP_ERROR_NOTSUPPORTED; 229 if (!compositor_)
230 return PP_ERROR_BADRESOURCE;
231
232 if (compositor_->IsInProgress())
233 return PP_ERROR_INPROGRESS;
234
235 data_.clip_rect = rect ? *rect : PP_MakeRectFromXYWH(0, 0, 0, 0);
236 return PP_OK;
48 } 237 }
49 238
50 int32_t CompositorLayerResource::SetTransform(const float matrix[16]) { 239 int32_t CompositorLayerResource::SetTransform(const float matrix[16]) {
51 return PP_ERROR_NOTSUPPORTED; 240 if (!compositor_)
241 return PP_ERROR_BADRESOURCE;
242
243 if (compositor_->IsInProgress())
244 return PP_ERROR_INPROGRESS;
245
246 std::copy(matrix, matrix + 16, data_.transform);
247 return PP_OK;
52 } 248 }
53 249
54 int32_t CompositorLayerResource::SetOpacity(float opacity) { 250 int32_t CompositorLayerResource::SetOpacity(float opacity) {
55 return PP_ERROR_NOTSUPPORTED; 251 if (!compositor_)
252 return PP_ERROR_BADRESOURCE;
253
254 if (compositor_->IsInProgress())
255 return PP_ERROR_INPROGRESS;
256
257 data_.opacity = clamp(opacity);
258 return PP_OK;
56 } 259 }
57 260
58 int32_t CompositorLayerResource::SetBlendMode(PP_BlendMode mode) { 261 int32_t CompositorLayerResource::SetBlendMode(PP_BlendMode mode) {
59 return PP_ERROR_NOTSUPPORTED; 262 if (!compositor_)
263 return PP_ERROR_BADRESOURCE;
264
265 if (compositor_->IsInProgress())
266 return PP_ERROR_INPROGRESS;
267
268 switch (mode) {
269 case PP_BLENDMODE_NONE:
270 case PP_BLENDMODE_SRC_OVER:
271 data_.blend_mode = mode;
272 return PP_OK;
273 }
274 return PP_ERROR_BADARGUMENT;
60 } 275 }
61 276
62 int32_t CompositorLayerResource::SetSourceRect( 277 int32_t CompositorLayerResource::SetSourceRect(
63 const PP_FloatRect* rect) { 278 const PP_FloatRect* rect) {
64 return PP_ERROR_NOTSUPPORTED; 279 return PP_ERROR_NOTSUPPORTED;
280 if (!compositor_)
281 return PP_ERROR_BADRESOURCE;
282
283 if (compositor_->IsInProgress())
284 return PP_ERROR_INPROGRESS;
285
286 if (!rect ||
287 rect->point.x < 0.0f ||
288 rect->point.y < 0.0f ||
289 rect->point.x + rect->size.width > source_size_.width ||
290 rect->point.y + rect->size.height > source_size_.height) {
291 return PP_ERROR_BADARGUMENT;
292 }
293
294 switch (data_.type) {
295 case CompositorLayerData::TYPE_TEXTURE:
296 data_.texture.source_rect = *rect;
297 return PP_OK;
298 case CompositorLayerData::TYPE_IMAGE:
299 data_.image.source_rect = *rect;
300 return PP_OK;
301 case CompositorLayerData::TYPE_UNKNOWN:
302 case CompositorLayerData::TYPE_COLOR:
303 break;
304 }
305 return PP_ERROR_BADARGUMENT;
65 } 306 }
66 307
67 int32_t CompositorLayerResource::SetPremultipliedAlpha(PP_Bool premult) { 308 int32_t CompositorLayerResource::SetPremultipliedAlpha(PP_Bool premult) {
68 return PP_ERROR_NOTSUPPORTED; 309 if (!compositor_)
310 return PP_ERROR_BADRESOURCE;
311
312 if (compositor_->IsInProgress())
313 return PP_ERROR_INPROGRESS;
314
315 if (data_.type != CompositorLayerData::TYPE_TEXTURE)
316 return PP_ERROR_BADARGUMENT;
317
318 data_.texture.premult_alpha = PP_FromBool(premult);
319 return PP_OK;
320 }
321
322 bool CompositorLayerResource::SetType(CompositorLayerData::Type type) {
323 if (type != CompositorLayerData::TYPE_COLOR &&
324 type != CompositorLayerData::TYPE_TEXTURE &&
325 type != CompositorLayerData::TYPE_IMAGE) {
326 NOTREACHED();
327 return false;
328 }
329
330 if (type != data_.type) {
331 if (data_.type != CompositorLayerData::TYPE_UNKNOWN)
332 return false;
333 data_.type = type;
334 }
335 return true;
336 }
337
338 int32_t CompositorLayerResource::CheckForSetTextureAndImage(
339 CompositorLayerData::Type type,
340 const scoped_refptr<TrackedCallback>& release_callback) {
341 if (!compositor_)
342 return PP_ERROR_BADRESOURCE;
343
344 if (compositor_->IsInProgress())
345 return PP_ERROR_INPROGRESS;
346
347 if (!SetType(type))
348 return PP_ERROR_BADARGUMENT;
349
350 // The layer's image has been set and it is not committed.
351 if (!release_callback_.is_null())
352 return PP_ERROR_INPROGRESS;
353
354 // Do not allow using a block callback as a release callback.
355 if (release_callback->is_blocking())
356 return PP_ERROR_BADARGUMENT;
357
358 return PP_OK;
69 } 359 }
70 360
71 } // namespace proxy 361 } // namespace proxy
72 } // namespace ppapi 362 } // namespace ppapi
OLDNEW
« no previous file with comments | « ppapi/proxy/compositor_layer_resource.h ('k') | ppapi/proxy/compositor_resource.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698