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

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 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
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(TYPE_COLOR))
119 return PP_ERROR_BADARGUMENT;
120 DCHECK(data_.color);
121
122 if (!size)
123 return PP_ERROR_BADARGUMENT;
124
125
126 data_.color->red = clamp(red);
127 data_.color->green = clamp(green);
128 data_.color->blue = clamp(blue);
129 data_.color->alpha = clamp(alpha);
130 data_.common.size = *size;
131
132 return PP_OK;
29 } 133 }
30 134
31 int32_t CompositorLayerResource::SetTexture( 135 int32_t CompositorLayerResource::SetTexture(
32 PP_Resource context, 136 PP_Resource context,
33 uint32_t texture, 137 uint32_t texture,
34 const PP_Size* size, 138 const PP_Size* size,
35 const scoped_refptr<ppapi::TrackedCallback>& callback) { 139 const scoped_refptr<TrackedCallback>& release_callback) {
36 return PP_ERROR_NOTSUPPORTED; 140 int32_t rv = CheckForSetTextureAndImage(TYPE_TEXTURE, release_callback);
141 if (rv != PP_OK)
142 return rv;
143 DCHECK(data_.texture);
144
145 EnterResourceNoLock<PPB_Graphics3D_API> enter(context, true);
146 if (enter.failed())
147 return PP_ERROR_BADRESOURCE;
148
149 if (!size || size->width <= 0 || size->height <= 0)
150 return PP_ERROR_BADARGUMENT;
151
152 PPB_Graphics3D_Shared* graphics =
153 static_cast<PPB_Graphics3D_Shared*>(enter.object());
154
155 GLES2Implementation* gl = graphics->gles2_impl();
156 Scoped2DTextureBinder scoped_2d_texture_binder(gl, texture);
157
158 // Generate a Mailbox for the texture.
159 gl->GenMailboxCHROMIUM(data_.texture->mailbox.name);
160 gl->ProduceTextureCHROMIUM(GL_TEXTURE_2D, data_.texture->mailbox.name);
161
162 // Set the source size to (1, 1). It will be used to verify the source_rect
163 // passed to SetSourceRect().
164 source_size_ = PP_MakeFloatSize(1.0f, 1.0f);
165
166 data_.common.size = *size;
167 data_.common.resource_id = compositor_->GenerateResourceId();
168 data_.texture->sync_point = gl->InsertSyncPointCHROMIUM();
169 data_.texture->source_rect.point = PP_MakeFloatPoint(0.0f, 0.0f);
170 data_.texture->source_rect.size = source_size_;
171
172 release_callback_ = base::Bind(
173 &OnTextureReleased,
174 ScopedPPResource(pp_resource()), // Keep layer alive.
175 ScopedPPResource(context), // Keep context alive
176 texture,
177 release_callback);
178
179 return PP_OK_COMPLETIONPENDING;
37 } 180 }
38 181
39 int32_t CompositorLayerResource::SetImage( 182 int32_t CompositorLayerResource::SetImage(
40 PP_Resource image_data, 183 PP_Resource image_data,
41 const PP_Size* size, 184 const PP_Size* size,
42 const scoped_refptr<ppapi::TrackedCallback>& callback) { 185 const scoped_refptr<TrackedCallback>& release_callback) {
43 return PP_ERROR_NOTSUPPORTED; 186 int32_t rv = CheckForSetTextureAndImage(TYPE_IMAGE, release_callback);
187 if (rv != PP_OK)
188 return rv;
189 DCHECK(data_.image);
190
191 EnterResourceNoLock<PPB_ImageData_API> enter(image_data, true);
192 if (enter.failed())
193 return PP_ERROR_BADRESOURCE;
194
195 PP_ImageDataDesc desc;
196 if (!enter.object()->Describe(&desc))
197 return PP_ERROR_BADARGUMENT;
198
199 // TODO(penghuang): Support image which width * 4 != stride.
200 if (desc.size.width * 4 != desc.stride)
201 return PP_ERROR_BADARGUMENT;
202
203 // TODO(penghuang): Support all formats.
204 if (desc.format != PP_IMAGEDATAFORMAT_RGBA_PREMUL)
205 return PP_ERROR_BADARGUMENT;
206
207 if (!size || size->width <= 0 || size->height <= 0)
208 return PP_ERROR_BADARGUMENT;
209
210 // Set the source size to image's size. It will be used to verify
211 // the source_rect passed to SetSourceRect().
212 source_size_ = PP_MakeFloatSize(desc.size.width, desc.size.height);
213
214 data_.common.size = size ? *size : desc.size;
215 data_.common.resource_id = compositor_->GenerateResourceId();
216 data_.image->resource = enter.resource()->host_resource().host_resource();
217 data_.image->source_rect.point = PP_MakeFloatPoint(0.0f, 0.0f);
218 data_.image->source_rect.size = source_size_;
219
220 release_callback_ = base::Bind(
221 &OnImageReleased,
222 ScopedPPResource(pp_resource()), // Keep layer alive.
223 ScopedPPResource(image_data), // Keep image_data alive.
224 release_callback);
225
226 return PP_OK_COMPLETIONPENDING;
44 } 227 }
45 228
46 int32_t CompositorLayerResource::SetClipRect(const PP_Rect* rect) { 229 int32_t CompositorLayerResource::SetClipRect(const PP_Rect* rect) {
47 return PP_ERROR_NOTSUPPORTED; 230 if (!compositor_)
231 return PP_ERROR_BADRESOURCE;
232
233 if (compositor_->IsInProgress())
234 return PP_ERROR_INPROGRESS;
235
236 data_.common.clip_rect = rect ? *rect : PP_MakeRectFromXYWH(0, 0, 0, 0);
237 return PP_OK;
48 } 238 }
49 239
50 int32_t CompositorLayerResource::SetTransform(const float matrix[16]) { 240 int32_t CompositorLayerResource::SetTransform(const float matrix[16]) {
51 return PP_ERROR_NOTSUPPORTED; 241 if (!compositor_)
242 return PP_ERROR_BADRESOURCE;
243
244 if (compositor_->IsInProgress())
245 return PP_ERROR_INPROGRESS;
246
247 std::copy(matrix, matrix + 16, data_.common.transform.matrix);
248 return PP_OK;
52 } 249 }
53 250
54 int32_t CompositorLayerResource::SetOpacity(float opacity) { 251 int32_t CompositorLayerResource::SetOpacity(float opacity) {
55 return PP_ERROR_NOTSUPPORTED; 252 if (!compositor_)
253 return PP_ERROR_BADRESOURCE;
254
255 if (compositor_->IsInProgress())
256 return PP_ERROR_INPROGRESS;
257
258 data_.common.opacity = clamp(opacity);
259 return PP_OK;
56 } 260 }
57 261
58 int32_t CompositorLayerResource::SetBlendMode(PP_BlendMode mode) { 262 int32_t CompositorLayerResource::SetBlendMode(PP_BlendMode mode) {
59 return PP_ERROR_NOTSUPPORTED; 263 if (!compositor_)
264 return PP_ERROR_BADRESOURCE;
265
266 if (compositor_->IsInProgress())
267 return PP_ERROR_INPROGRESS;
268
269 switch (mode) {
270 case PP_BLENDMODE_NONE:
271 case PP_BLENDMODE_SRC_OVER:
272 data_.common.blend_mode = mode;
273 return PP_OK;
274 }
275 return PP_ERROR_BADARGUMENT;
60 } 276 }
61 277
62 int32_t CompositorLayerResource::SetSourceRect( 278 int32_t CompositorLayerResource::SetSourceRect(
63 const PP_FloatRect* rect) { 279 const PP_FloatRect* rect) {
64 return PP_ERROR_NOTSUPPORTED; 280 return PP_ERROR_NOTSUPPORTED;
281 if (!compositor_)
282 return PP_ERROR_BADRESOURCE;
283
284 if (compositor_->IsInProgress())
285 return PP_ERROR_INPROGRESS;
286
287 if (!rect ||
288 rect->point.x < 0.0f ||
289 rect->point.y < 0.0f ||
290 rect->point.x + rect->size.width > source_size_.width ||
291 rect->point.y + rect->size.height > source_size_.height) {
292 return PP_ERROR_BADARGUMENT;
293 }
294
295 if (data_.texture) {
296 data_.texture->source_rect = *rect;
297 return PP_OK;
298 }
299 if (data_.image) {
300 data_.image->source_rect = *rect;
301 return PP_OK;
302 }
303 return PP_ERROR_BADARGUMENT;
65 } 304 }
66 305
67 int32_t CompositorLayerResource::SetPremultipliedAlpha(PP_Bool premult) { 306 int32_t CompositorLayerResource::SetPremultipliedAlpha(PP_Bool premult) {
68 return PP_ERROR_NOTSUPPORTED; 307 if (!compositor_)
308 return PP_ERROR_BADRESOURCE;
309
310 if (compositor_->IsInProgress())
311 return PP_ERROR_INPROGRESS;
312
313 if (data_.texture) {
314 data_.texture->premult_alpha = PP_FromBool(premult);
315 return PP_OK;
316 }
317 return PP_ERROR_BADARGUMENT;
318 }
319
320 bool CompositorLayerResource::SetType(LayerType type) {
321 if (type == TYPE_COLOR) {
322 if (data_.is_null())
323 data_.color.reset(new CompositorLayerData::ColorLayer());
324 return data_.color;
325 }
326
327 if (type == TYPE_TEXTURE) {
328 if (data_.is_null())
329 data_.texture.reset(new CompositorLayerData::TextureLayer());
330 return data_.texture;
331 }
332
333 if (type == TYPE_IMAGE) {
334 if (data_.is_null())
335 data_.image.reset(new CompositorLayerData::ImageLayer());
336 return data_.image;
337 }
338
339 // Should not be reached.
340 DCHECK(false);
341 return false;
342 }
343
344 int32_t CompositorLayerResource::CheckForSetTextureAndImage(
345 LayerType type,
346 const scoped_refptr<TrackedCallback>& release_callback) {
347 if (!compositor_)
348 return PP_ERROR_BADRESOURCE;
349
350 if (compositor_->IsInProgress())
351 return PP_ERROR_INPROGRESS;
352
353 if (!SetType(type))
354 return PP_ERROR_BADARGUMENT;
355
356 // The layer's image has been set and it is not committed.
357 if (!release_callback_.is_null())
358 return PP_ERROR_INPROGRESS;
359
360 // Do not allow using a block callback as a release callback.
361 if (release_callback->is_blocking())
362 return PP_ERROR_BADARGUMENT;
363
364 return PP_OK;
69 } 365 }
70 366
71 } // namespace proxy 367 } // namespace proxy
72 } // namespace ppapi 368 } // namespace ppapi
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698