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

Side by Side Diff: content/renderer/pepper/pepper_compositor_host.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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "content/renderer/pepper/pepper_compositor_host.h"
6
7 #include "base/logging.h"
8 #include "cc/layers/texture_layer.h"
9 #include "cc/resources/texture_mailbox.h"
10 #include "content/public/renderer/renderer_ppapi_host.h"
11 #include "content/renderer/pepper/gfx_conversion.h"
12 #include "content/renderer/pepper/host_globals.h"
13 #include "content/renderer/pepper/pepper_plugin_instance_impl.h"
14 #include "content/renderer/pepper/ppb_image_data_impl.h"
15 #include "ppapi/c/pp_errors.h"
16 #include "ppapi/host/dispatch_host_message.h"
17 #include "ppapi/host/host_message_context.h"
18 #include "ppapi/host/ppapi_host.h"
19 #include "ppapi/proxy/ppapi_messages.h"
20 #include "ppapi/thunk/enter.h"
21 #include "ppapi/thunk/ppb_image_data_api.h"
22 #include "third_party/khronos/GLES2/gl2.h"
23 #include "ui/gfx/transform.h"
24
25 using ppapi::host::HostMessageContext;
26 using ppapi::thunk::EnterResourceNoLock;
27 using ppapi::thunk::PPB_ImageData_API;
28
29 namespace content {
30
31 PepperCompositorHost::PepperCompositorHost(
32 RendererPpapiHost* host,
33 PP_Instance instance,
34 PP_Resource resource)
35 : ResourceHost(host->GetPpapiHost(), instance, resource),
36 bound_instance_(NULL),
37 weak_factory_(this) {
38 layer_ = cc::SolidColorLayer::Create();
39 layer_->SetMasksToBounds(true);
40 layer_->SetIsDrawable(true);
41 }
42
43 PepperCompositorHost::~PepperCompositorHost() {
44 // Unbind from the instance when destroyed if we're still bound.
45 if (bound_instance_)
46 bound_instance_->BindGraphics(bound_instance_->pp_instance(), 0);
47 }
48
49 bool PepperCompositorHost::BindToInstance(
50 PepperPluginInstanceImpl* new_instance) {
51 if (new_instance && new_instance->pp_instance() != pp_instance())
52 return false; // Can't bind other instance's contexts.
53 if (bound_instance_ == new_instance)
54 return true; // Rebinding the same device, nothing to do.
55 if (bound_instance_ && new_instance)
56 return false; // Can't change a bound device.
57 bound_instance_ = new_instance;
58 return true;
59 }
60
61 void PepperCompositorHost::ViewInitiatedPaint() {
62 if (!commit_layers_reply_context_.is_valid())
63 return;
64 host()->SendReply(commit_layers_reply_context_,
65 PpapiPluginMsg_Compositor_CommitLayersReply());
66 commit_layers_reply_context_ = ppapi::host::ReplyMessageContext();
67 }
68
69 void PepperCompositorHost::ViewFlushedPaint() {}
70
71 void PepperCompositorHost::ResourceReleased(int32_t id,
72 uint32_t sync_point,
73 bool is_lost) {
74 host()->SendUnsolicitedReply(
75 pp_resource(),
76 PpapiPluginMsg_Compositor_ReleaseResource(id, sync_point, is_lost));
77 }
78
79 void PepperCompositorHost::ImageReleased(
80 int32_t id,
81 scoped_ptr<base::SharedMemory> shared_memory,
82 uint32_t sync_point,
83 bool is_lost) {
84 ResourceReleased(id, sync_point, is_lost);
85 }
86
87 int32_t PepperCompositorHost::OnResourceMessageReceived(
88 const IPC::Message& msg,
89 HostMessageContext* context) {
90 PPAPI_BEGIN_MESSAGE_MAP(PepperCompositorHost, msg)
91 PPAPI_DISPATCH_HOST_RESOURCE_CALL(
92 PpapiHostMsg_Compositor_CommitLayers, OnHostMsgCommitLayers)
93 PPAPI_END_MESSAGE_MAP()
94 return ppapi::host::ResourceHost::OnResourceMessageReceived(msg, context);
95 }
96
97 bool PepperCompositorHost::IsCompositorHost() {
98 return true;
99 }
100
101 void PepperCompositorHost::UpdateLayer(
102 const scoped_refptr<cc::Layer>& layer,
103 const ppapi::CompositorLayerData* old_layer,
104 const ppapi::CompositorLayerData* new_layer) {
105 CHECK(!old_layer || new_layer->type == old_layer->type);
106
107 // Always update properties on cc::Layer, because cc::Layer
108 // will ignore any setting with unchanged value.
109 layer->SetBounds(PP_ToGfxSize((new_layer)->size));
110 layer->SetBlendMode(SkXfermode::kSrcOver_Mode);
111 layer->SetOpacity(new_layer->opacity / 255.0f);
112
113 gfx::Transform transform(gfx::Transform::kSkipInitialization);
114 transform.matrix().setColMajorf(new_layer->transform);
115 layer->SetTransform(transform);
116
117 // Consider a (0,0,0,0) rect as no clip rect.
118 if (new_layer->clip_rect.point.x != 0 ||
119 new_layer->clip_rect.point.y != 0 ||
120 new_layer->clip_rect.size.width != 0 ||
121 new_layer->clip_rect.size.height != 0) {
122 if (!layer->mask_layer())
123 layer->SetMaskLayer(cc::Layer::Create());
124 layer->mask_layer()->SetPosition(PP_ToGfxPoint(new_layer->clip_rect.point));
125 layer->mask_layer()->SetBounds(PP_ToGfxSize(new_layer->clip_rect.size));
126 } else {
127 layer->SetMaskLayer(NULL);
128 }
129
130 if (new_layer->type == ppapi::CompositorLayerData::TYPE_COLOR) {
131 layer->SetBackgroundColor(SkColorSetARGBMacro(new_layer->color.alpha,
132 new_layer->color.red,
133 new_layer->color.green,
134 new_layer->color.blue));
135 } else if (new_layer->type == ppapi::CompositorLayerData::TYPE_TEXTURE) {
136 scoped_refptr<cc::TextureLayer> texture_layer(
137 static_cast<cc::TextureLayer*>(layer.get()));
138 if (!old_layer || new_layer->texture.id != old_layer->texture.id) {
139 gpu::Mailbox gpu_mailbox;
140 gpu_mailbox.SetName(new_layer->texture.mailbox);
141 cc::TextureMailbox mailbox(gpu_mailbox,
142 GL_TEXTURE_2D,
143 new_layer->texture.sync_point);
144 texture_layer->SetTextureMailbox(mailbox,
145 cc::SingleReleaseCallback::Create(
146 base::Bind(&PepperCompositorHost::ResourceReleased,
147 weak_factory_.GetWeakPtr(),
148 new_layer->texture.id)));;
149 }
150 texture_layer->SetPremultipliedAlpha(new_layer->texture.premult_alpha);
151 gfx::RectF rect = PP_ToGfxRectF(new_layer->texture.source_rect);
152 texture_layer->SetUV(rect.origin(), rect.bottom_right());
153 } else if (new_layer->type == ppapi::CompositorLayerData::TYPE_IMAGE) {
154 if (!old_layer || new_layer->image.id != old_layer->image.id) {
155 scoped_refptr<cc::TextureLayer> image_layer(
156 static_cast<cc::TextureLayer*>(layer.get()));
157 EnterResourceNoLock<PPB_ImageData_API> enter(
158 new_layer->image.host_resource, true);
159
160 CHECK(enter.succeeded()) << "Image is invalid!";
161 PP_ImageDataDesc desc;
162 CHECK(enter.object()->Describe(&desc)) << "Can not describe the image!";
163
164 // TODO(penghuang): support all kinds of image.
165 CHECK_EQ(desc.stride, desc.size.width * 4);
166 CHECK_EQ(desc.format, PP_IMAGEDATAFORMAT_RGBA_PREMUL);
167
168 int handle;
169 uint32_t byte_count;
170 CHECK_EQ(enter.object()->GetSharedMemory(&handle, &byte_count), PP_OK)
171 <<"Can not access the image's shared memory!";
raymes 2014/06/04 01:11:38 You might as well keep all of these checks in now,
Peng 2014/06/05 00:50:38 Done.
172 #if defined(OS_WIN)
173 base::SharedMemoryHandle shm_handle =
174 static_cast<base::SharedMemoryHandle>(_dup(handle));
175 #else
176 base::SharedMemoryHandle shm_handle(dup(handle), false);
177 #endif
178 // Use a scoped_ptr to keep shared_memory alive until
179 // PepperCompositorHost::ImageReleased is called.
180 scoped_ptr<base::SharedMemory> shared_memory(
181 new base::SharedMemory(shm_handle, true));
182 CHECK(shared_memory->Map(desc.stride * desc.size.height));
183 cc::TextureMailbox mailbox(shared_memory.get(),
184 PP_ToGfxSize(desc.size));
185 image_layer->SetTextureMailbox(mailbox,
186 cc::SingleReleaseCallback::Create(
187 base::Bind(&PepperCompositorHost::ImageReleased,
188 weak_factory_.GetWeakPtr(),
189 new_layer->image.id,
190 base::Passed(&shared_memory))));
191
192 // ImageData is always premultiplied alpha.
193 image_layer->SetPremultipliedAlpha(true);
194 }
195 } else {
196 NOTREACHED();
197 }
198 }
199
200 int32_t PepperCompositorHost::OnHostMsgCommitLayers(
201 HostMessageContext* context,
202 const std::vector<ppapi::CompositorLayerData>& layers,
203 bool reset) {
204 // Do not support CommitLayers on an unbounded compositor.
205 if (!bound_instance_)
206 return PP_ERROR_FAILED;
207
208 CHECK(!commit_layers_reply_context_.is_valid());
209 commit_layers_reply_context_ = context->MakeReplyMessageContext();
210
211 // ResetLayers() has been called, we need rebuild layer stack.
212 if (reset) {
213 layer_->RemoveAllChildren();
214 cc_layers_.clear();
215 pp_layers_.clear();
216 }
217
218 for (size_t i = 0; i < layers.size(); ++i) {
219 const ppapi::CompositorLayerData& pp_layer = layers[i];
220 ppapi::CompositorLayerData* old_layer =
221 i >= pp_layers_.size() ? NULL : &pp_layers_[i];
222 scoped_refptr<cc::Layer> cc_layer =
223 i >= cc_layers_.size() ? NULL : cc_layers_[i];
224
225 CHECK((old_layer && cc_layer) || (!old_layer && !cc_layer));
226
227 if (!cc_layer) {
228 if (pp_layer.type == ppapi::CompositorLayerData::TYPE_COLOR) {
229 cc_layer = cc::SolidColorLayer::Create();
230 } else if (pp_layer.type == ppapi::CompositorLayerData::TYPE_TEXTURE ||
231 pp_layer.type == ppapi::CompositorLayerData::TYPE_IMAGE) {
232 cc_layer = cc::TextureLayer::CreateForMailbox(NULL);
233 } else {
234 NOTREACHED();
235 }
236 cc_layer->SetIsDrawable(true);
237 cc_layer->SetAnchorPoint(gfx::PointF());
238 }
239
240 UpdateLayer(cc_layer, old_layer, &pp_layer);
241
242 if (old_layer) {
243 *old_layer = pp_layer;
244 } else {
245 layer_->AddChild(cc_layer);
246 cc_layers_.push_back(cc_layer);
247 pp_layers_.push_back(pp_layer);
248 }
249 }
250 return PP_OK_COMPLETIONPENDING;
251 }
252
253 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698