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

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

Issue 298023004: [PPAPI] Compositor API implementation (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@compositor_api_def_new
Patch Set: Update 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_resource.h" 5 #include "ppapi/proxy/compositor_resource.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "gpu/command_buffer/client/gles2_implementation.h" 10 #include "gpu/command_buffer/client/gles2_implementation.h"
11 #include "gpu/command_buffer/common/mailbox.h" 11 #include "gpu/command_buffer/common/mailbox.h"
12 #include "ppapi/proxy/compositor_layer_resource.h"
12 #include "ppapi/proxy/ppapi_messages.h" 13 #include "ppapi/proxy/ppapi_messages.h"
13 #include "ppapi/shared_impl/ppb_graphics_3d_shared.h" 14 #include "ppapi/shared_impl/ppb_graphics_3d_shared.h"
14 #include "ppapi/shared_impl/var.h" 15 #include "ppapi/shared_impl/var.h"
15 #include "ppapi/thunk/enter.h" 16 #include "ppapi/thunk/enter.h"
16 #include "ppapi/thunk/ppb_graphics_3d_api.h" 17 #include "ppapi/thunk/ppb_graphics_3d_api.h"
18 #include "ppapi/thunk/ppb_image_data_api.h"
17 19
18 using ppapi::thunk::EnterResourceNoLock; 20 using ppapi::thunk::EnterResourceNoLock;
19 using ppapi::thunk::PPB_Graphics3D_API; 21 using ppapi::thunk::PPB_Graphics3D_API;
20 22
21 namespace ppapi { 23 namespace ppapi {
22 namespace proxy { 24 namespace proxy {
23 25
26 namespace {
27
28 class Scoped2DTextureBinder {
29 public:
30 Scoped2DTextureBinder(gpu::gles2::GLES2Implementation* gl, uint32_t id)
31 : gl_(gl), old_id_(-1) {
32 gl_->GetIntegerv(GL_TEXTURE_BINDING_2D, &old_id_);
33 gl_->BindTexture(GL_TEXTURE_2D, id);
34 }
35
36 ~Scoped2DTextureBinder() {
37 gl_->BindTexture(GL_TEXTURE_2D, old_id_);
38 }
39
40 private:
41 gpu::gles2::GLES2Implementation* gl_;
42 int32_t old_id_;
43 };
44
45 } // namespace
46
47 CompositorResource::Layer::Layer(CompositorResource* compositor)
48 : compositor_(compositor),
49 source_size_(PP_MakeFloatSize(0.0f, 0.0f)) {
50 }
51
52 CompositorResource::Layer::~Layer() {}
53
54 int32_t CompositorResource::Layer::SetColor(
55 uint8_t red,
56 uint8_t green,
57 uint8_t blue,
58 uint8_t alpha,
59 const struct PP_Size* size) {
60 if (compositor_->IsInProgress())
61 return PP_ERROR_INPROGRESS;
62
63 if (!SetType(CompositorLayer::TYPE_COLOR))
64 return PP_ERROR_BADARGUMENT;
65
66 if (!size)
67 return PP_ERROR_BADARGUMENT;
68
69 data_.color.red = red;
70 data_.color.green = green;
71 data_.color.blue = blue;
72 data_.color.alpha = alpha;
73 data_.size = *size;
74
75 return PP_OK;
76 }
77
78 int32_t CompositorResource::Layer::SetTexture(
79 PP_Resource context,
80 uint32_t texture,
81 const struct PP_Size* size,
82 const scoped_refptr<ppapi::TrackedCallback>& release_callback) {
83 if (compositor_->IsInProgress())
84 return PP_ERROR_INPROGRESS;
85
86 if (!SetType(CompositorLayer::TYPE_TEXTURE))
87 return PP_ERROR_BADARGUMENT;
88
89 // The layer's texture has been set and it is not committed.
90 if (!release_callback_.is_null())
91 return PP_ERROR_INPROGRESS;
92
93 EnterResourceNoLock<PPB_Graphics3D_API> enter(context, true);
94 if (enter.failed())
95 return PP_ERROR_BADARGUMENT;
96
97 if (!size || size->width <= 0 || size->height <= 0)
98 return PP_ERROR_BADARGUMENT;
99
100 // Do not allow using a block callback as a release callback.
101 if (release_callback->is_blocking())
102 return PP_ERROR_BADARGUMENT;
103
104 PPB_Graphics3D_Shared* graphics =
105 static_cast<PPB_Graphics3D_Shared*>(enter.object());
106
107 gpu::gles2::GLES2Implementation* gl = graphics->gles2_impl();
108 Scoped2DTextureBinder scoped_2d_texture_binder(gl, texture);
109
110 // Generate a Mailbox for the texture.
111 gl->GenMailboxCHROMIUM(data_.texture.mailbox);
112 gl->ProduceTextureCHROMIUM(GL_TEXTURE_2D, data_.texture.mailbox);
113
114 // Set the source size to (1, 1). It will be used to verify the source_rect
115 // passed to SetSourceRect().
116 source_size_ = PP_MakeFloatSize(1.0f, 1.0f);
117
118 data_.texture.id = compositor_->GenerateResourceId();
119 data_.texture.sync_point = gl->InsertSyncPointCHROMIUM();
120 data_.size = *size;
121 data_.texture.source_rect.point = PP_MakeFloatPoint(0.0f, 0.0f);
122 data_.texture.source_rect.size = source_size_;
123
124 release_callback_ = base::Bind(
125 &CompositorResource::Layer::OnTextureReleased,
126 AsWeakPtr(),
127 ScopedPPResource(context), // Keep context alive
128 texture,
129 release_callback);
130
131 return PP_OK_COMPLETIONPENDING;
132 }
133
134 int32_t CompositorResource::Layer::SetImage(
135 PP_Resource image_data,
136 const struct PP_Size* size,
137 const scoped_refptr<ppapi::TrackedCallback>& release_callback) {
138 if (compositor_->IsInProgress())
139 return PP_ERROR_INPROGRESS;
140
141 if (!SetType(CompositorLayer::TYPE_IMAGE))
142 return PP_ERROR_BADARGUMENT;
143
144 EnterResourceNoLock<thunk::PPB_ImageData_API> enter(image_data, true);
145 if (enter.failed())
146 return PP_ERROR_BADARGUMENT;
147
148 // The layer's image has been set and it is not committed.
149 if (!release_callback_.is_null())
150 return PP_ERROR_INPROGRESS;
151
152 PP_ImageDataDesc desc;
153 if (!enter.object()->Describe(&desc))
154 return PP_ERROR_BADARGUMENT;
155
156 // TODO(penghuang): Support image which width * 4 != stride.
157 if (desc.size.width * 4 != desc.stride)
158 return PP_ERROR_BADARGUMENT;
159
160 // TODO(penghuang): Support all formats.
161 if (desc.format != PP_IMAGEDATAFORMAT_RGBA_PREMUL)
162 return PP_ERROR_BADARGUMENT;
163
164 if (!size || size->width <= 0 || size->height <= 0)
165 return PP_ERROR_BADARGUMENT;
166
167 // Do not allow using a block callback as a release callback.
168 if (release_callback->is_blocking())
169 return PP_ERROR_BADARGUMENT;
170
171 // Set the source size to image'size. It will be used to verify
raymes 2014/06/02 03:51:08 to the image's size
Peng 2014/06/02 19:01:55 Done.
172 // the source_rect passed to SetSourceRect().
173 source_size_ = PP_MakeFloatSize(desc.size.width, desc.size.height);
174
175 data_.size = size ? *size : desc.size;
176 data_.image.id = compositor_->GenerateResourceId();
177 data_.image.instance = enter.resource()->host_resource().instance();
178 data_.image.host_resource = enter.resource()->host_resource().host_resource();
179 data_.image.source_rect.point = PP_MakeFloatPoint(0.0f, 0.0f);
180 data_.image.source_rect.size = source_size_;
181
182 release_callback_ = base::Bind(
183 &CompositorResource::Layer::OnImageReleased,
184 AsWeakPtr(),
185 ScopedPPResource(image_data), // Keep image_data alive.
186 release_callback);
187
188 return PP_OK_COMPLETIONPENDING;
189 }
190
191 int32_t CompositorResource::Layer::SetClipRect(const struct PP_Rect* rect) {
192 if (compositor_->IsInProgress())
193 return PP_ERROR_INPROGRESS;
194
195 data_.clip_rect = rect ? *rect : PP_MakeRectFromXYWH(0, 0, 0, 0);
196 return PP_OK;
197 }
198
199 int32_t CompositorResource::Layer::SetTransform(const float matrix[16]) {
200 if (compositor_->IsInProgress())
201 return PP_ERROR_INPROGRESS;
202
203 std::copy(matrix, matrix + 16, data_.transform);
raymes 2014/06/02 03:51:08 matrix + arraysize(matrix)?
Peng 2014/06/02 19:01:55 arraysize() does not work here. Probably it is bec
204 return PP_OK;
205 }
206
207 int32_t CompositorResource::Layer::SetOpacity(uint8_t opacity) {
208 if (compositor_->IsInProgress())
209 return PP_ERROR_INPROGRESS;
210
211 data_.opacity = opacity;
212 return PP_OK;
213 }
214
215 int32_t CompositorResource::Layer::SetBlendMode(PP_BlendMode mode) {
216 if (compositor_->IsInProgress())
217 return PP_ERROR_INPROGRESS;
218
219 switch (mode) {
220 case PP_BLENDMODE_NONE:
221 case PP_BLENDMODE_SRC_OVER:
222 data_.blend_mode = mode;
223 return PP_OK;
224 default:
225 return PP_ERROR_BADARGUMENT;
raymes 2014/06/02 03:51:08 Maybe remove the default because we won't get comp
Peng 2014/06/02 19:01:55 Done.
226 }
227 }
228
229 int32_t CompositorResource::Layer::SetSourceRect(
230 const struct PP_FloatRect* rect) {
231 if (compositor_->IsInProgress())
232 return PP_ERROR_INPROGRESS;
233
234 if (!rect ||
235 rect->point.x < 0.0f ||
236 rect->point.y < 0.0f ||
237 rect->point.x + rect->size.width > source_size_.width ||
238 rect->point.y + rect->size.height > source_size_.height)
239 return PP_ERROR_BADARGUMENT;
240
241 switch (data_.type) {
242 case CompositorLayer::TYPE_TEXTURE:
243 data_.texture.source_rect = *rect;
244 return PP_OK;
245 case CompositorLayer::TYPE_IMAGE:
246 data_.image.source_rect = *rect;
247 return PP_OK;
248 default:
249 return PP_ERROR_BADARGUMENT;
250 }
251 }
252
253 int32_t CompositorResource::Layer::SetPremultipliedAlpha(PP_Bool premult) {
254 if (compositor_->IsInProgress())
255 return PP_ERROR_INPROGRESS;
256
257 if (data_.type != CompositorLayer::TYPE_TEXTURE)
258 return PP_ERROR_BADARGUMENT;
259
260 data_.texture.premult_alpha = PP_FromBool(premult);
261 return PP_OK;
262 }
263
264 bool CompositorResource::Layer::SetType(CompositorLayer::Type type) {
265 DCHECK(type == CompositorLayer::TYPE_COLOR ||
266 type == CompositorLayer::TYPE_TEXTURE ||
267 type == CompositorLayer::TYPE_IMAGE);
raymes 2014/06/02 03:51:08 If this is not the case, should we return false he
Peng 2014/06/02 19:01:55 Because this function is for internal using only (
268 if (type != data_.type) {
269 if (data_.type != CompositorLayer::TYPE_UNKNOWN)
270 return false;
271 data_.type = type;
272 }
273 return true;
274 }
275
276 void CompositorResource::Layer::OnTextureReleased(
277 const ScopedPPResource& context,
278 uint32_t texture,
279 const scoped_refptr<TrackedCallback>& release_callback,
280 uint32_t sync_point,
281 bool is_lost) {
282 do {
283 if (!sync_point)
284 break;
285
286 EnterResourceNoLock<PPB_Graphics3D_API> enter(context.get(), true);
287 if (enter.failed())
288 break;;
raymes 2014/06/02 03:51:08 extra ;
Peng 2014/06/02 19:01:55 Done.
289
290 PPB_Graphics3D_Shared* graphics =
291 static_cast<PPB_Graphics3D_Shared*>(enter.object());
292
293 gpu::gles2::GLES2Implementation* gl = graphics->gles2_impl();
294 gl->WaitSyncPointCHROMIUM(sync_point);
295 } while (false);
296
297 release_callback->Run(PP_OK);
298 }
299
300 void CompositorResource::Layer::OnImageReleased(
301 const ScopedPPResource& image,
302 const scoped_refptr<TrackedCallback>& release_callback,
303 uint32_t sync_point,
304 bool is_lost) {
305 release_callback->Run(PP_OK);
306 }
307
24 CompositorResource::CompositorResource(Connection connection, 308 CompositorResource::CompositorResource(Connection connection,
25 PP_Instance instance) 309 PP_Instance instance)
26 : PluginResource(connection, instance) { 310 : PluginResource(connection, instance),
311 layer_changed_(true),
312 last_resource_id_(0) {
313 SendCreate(RENDERER, PpapiHostMsg_Compositor_Create());
27 } 314 }
28 315
29 CompositorResource::~CompositorResource() { 316 CompositorResource::~CompositorResource() {
30 } 317 }
31 318
32 thunk::PPB_Compositor_API* CompositorResource::AsPPB_Compositor_API() { 319 thunk::PPB_Compositor_API* CompositorResource::AsPPB_Compositor_API() {
33 return this; 320 return this;
34 } 321 }
35 322
323 void CompositorResource::OnReplyReceived(
324 const ResourceMessageReplyParams& params,
325 const IPC::Message& msg) {
326 PPAPI_BEGIN_MESSAGE_MAP(CompositorResource, msg)
327 PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL(
328 PpapiPluginMsg_Compositor_ReleaseResource,
329 OnPluginMsgReleaseResource)
330 PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL_UNHANDLED(
331 PluginResource::OnReplyReceived(params, msg))
332 PPAPI_END_MESSAGE_MAP()
333 }
334
36 PP_Resource CompositorResource::AddLayer() { 335 PP_Resource CompositorResource::AddLayer() {
37 return 0; 336 Layer* layer = new Layer(this);
337 layers_.push_back(layer);
338 CompositorLayerResource *resource = new CompositorLayerResource(
339 connection(), pp_instance(), layer->AsWeakPtr());
340 return resource->GetReference();
38 } 341 }
39 342
40 int32_t CompositorResource::CommitLayers( 343 int32_t CompositorResource::CommitLayers(
41 const scoped_refptr<ppapi::TrackedCallback>& callback) { 344 const scoped_refptr<ppapi::TrackedCallback>& callback) {
42 return PP_ERROR_NOTSUPPORTED; 345 if (IsInProgress())
346 return PP_ERROR_INPROGRESS;
347
348 std::vector<CompositorLayer> layers;
349 layers.reserve(layers_.size());
350
351 for (ScopedVector<Layer>::const_iterator it = layers_.begin();
352 it != layers_.end(); ++it) {
353 switch ((*it)->data().type) {
354 case CompositorLayer::TYPE_UNKNOWN:
355 return PP_ERROR_FAILED;
356 case CompositorLayer::TYPE_COLOR:
357 case CompositorLayer::TYPE_TEXTURE:
358 case CompositorLayer::TYPE_IMAGE:
359 layers.push_back((*it)->data());
360 continue;
361 default:
362 NOTREACHED();
363 }
364 }
365
366 commit_callback_ = callback;
367 Call<PpapiPluginMsg_Compositor_CommitLayersReply>(
368 RENDERER,
369 PpapiHostMsg_Compositor_CommitLayers(layers, layer_changed_),
370 base::Bind(&CompositorResource::OnPluginMsgCommitLayersReply,
371 base::Unretained(this)),
372 callback);
373
374 return PP_OK_COMPLETIONPENDING;
43 } 375 }
44 376
45 int32_t CompositorResource::ResetLayers() { 377 int32_t CompositorResource::ResetLayers() {
46 return PP_ERROR_NOTSUPPORTED; 378 if (IsInProgress())
379 return PP_ERROR_INPROGRESS;
380
381 // Call release_callback for every layer.
382 for (ScopedVector<Layer>::iterator it = layers_.begin();
383 it != layers_.end(); ++it) {
384 ReleaseCallback release_callback = (*it)->release_callback();
385 if (!release_callback.is_null())
386 release_callback.Run(0, false);
387 }
388
389 layers_.clear();
390 layer_changed_ = true;
raymes 2014/06/02 03:51:08 Does this mean that CommitLayers has to be called
Peng 2014/06/02 19:01:55 No. This function can be called with or without ca
raymes 2014/06/03 00:43:22 But the layers won't really be destroyed until Com
Peng 2014/06/03 18:32:23 I understand your point. This API only reset layer
391 return PP_OK;
392 }
393
394 void CompositorResource::OnPluginMsgCommitLayersReply(
395 const ResourceMessageReplyParams& params) {
396 if (!TrackedCallback::IsPending(commit_callback_))
397 return;
398
399 // On success, we put layers' release_callbacks into a map,
400 // otherwise we will do nothing. So plugin may change layers and
401 // call CommitLayers() again.
402 if (params.result() == PP_OK) {
403 layer_changed_ = false;
404 for (ScopedVector<Layer>::iterator it = layers_.begin();
405 it != layers_.end(); ++it) {
406 switch ((*it)->data().type) {
407 case CompositorLayer::TYPE_TEXTURE: {
408 ReleaseCallback release_callback = (*it)->release_callback();
409 (*it)->ResetReleaseCallback();
410 if (!release_callback.is_null()) {
411 release_callback_map_.insert(ReleaseCallbackMap::value_type(
412 (*it)->data().texture.id, release_callback));
raymes 2014/06/02 03:51:08 I think the indentation is off
Peng 2014/06/02 19:01:55 Sorry, what do you mean?
raymes 2014/06/03 00:43:22 I think there should just be 4 space indent from t
Peng 2014/06/03 18:32:23 Done.
413 }
414 break;
415 }
416 case CompositorLayer::TYPE_IMAGE: {
417 ReleaseCallback release_callback = (*it)->release_callback();
418 (*it)->ResetReleaseCallback();
419 if (!release_callback.is_null()) {
420 release_callback_map_.insert(ReleaseCallbackMap::value_type(
421 (*it)->data().image.id, release_callback));
raymes 2014/06/02 03:51:08 Why not just have a id for every ppapi::Compositor
Peng 2014/06/02 19:01:55 Actually this id is for the texture or image resou
raymes 2014/06/03 00:43:22 But we could just make it a layer ID instead right
Peng 2014/06/03 18:32:23 Moved it to toplevel structure, and renamed it to
422 }
423 break;
424 }
425 default:
426 break;
427 }
428 }
429 }
430
431 scoped_refptr<TrackedCallback> callback;
432 callback.swap(commit_callback_);
433 callback->Run(params.result());
434 }
435
436 void CompositorResource::OnPluginMsgReleaseResource(
437 const ResourceMessageReplyParams& params,
438 int32_t id,
439 uint32_t sync_point,
440 bool is_lost) {
441 ReleaseCallbackMap::iterator it = release_callback_map_.find(id);
442 DCHECK(it != release_callback_map_.end()) <<
443 "Can not found release_callback_ by id(" << id << ")!";
444 it->second.Run(sync_point, is_lost);
445 release_callback_map_.erase(it);
47 } 446 }
48 447
49 } // namespace proxy 448 } // namespace proxy
50 } // namespace ppapi 449 } // namespace ppapi
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698