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

Side by Side Diff: chrome/renderer/render_widget_fullscreen_pepper.cc

Issue 5994002: use accelerated compositing in fullscreen pepper (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 9 years, 11 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 "chrome/renderer/render_widget_fullscreen_pepper.h" 5 #include "chrome/renderer/render_widget_fullscreen_pepper.h"
6 6
7 #include "chrome/common/render_messages.h" 7 #include "chrome/common/render_messages.h"
8 #include "chrome/renderer/ggl/ggl.h"
9 #include "chrome/renderer/gpu_channel_host.h"
10 #include "chrome/renderer/pepper_platform_context_3d_impl.h"
8 #include "chrome/renderer/render_thread.h" 11 #include "chrome/renderer/render_thread.h"
12 #include "gpu/command_buffer/client/gles2_implementation.h"
9 #include "third_party/WebKit/WebKit/chromium/public/WebCursorInfo.h" 13 #include "third_party/WebKit/WebKit/chromium/public/WebCursorInfo.h"
10 #include "third_party/WebKit/WebKit/chromium/public/WebSize.h" 14 #include "third_party/WebKit/WebKit/chromium/public/WebSize.h"
11 #include "third_party/WebKit/WebKit/chromium/public/WebWidget.h" 15 #include "third_party/WebKit/WebKit/chromium/public/WebWidget.h"
12 #include "webkit/plugins/ppapi/fullscreen_container.h" 16 #include "webkit/plugins/ppapi/plugin_delegate.h"
13 #include "webkit/plugins/ppapi/ppapi_plugin_instance.h" 17 #include "webkit/plugins/ppapi/ppapi_plugin_instance.h"
14 18
15 using WebKit::WebCanvas; 19 using WebKit::WebCanvas;
16 using WebKit::WebCompositionUnderline; 20 using WebKit::WebCompositionUnderline;
17 using WebKit::WebCursorInfo; 21 using WebKit::WebCursorInfo;
18 using WebKit::WebInputEvent; 22 using WebKit::WebInputEvent;
19 using WebKit::WebRect; 23 using WebKit::WebRect;
20 using WebKit::WebSize; 24 using WebKit::WebSize;
21 using WebKit::WebString; 25 using WebKit::WebString;
22 using WebKit::WebTextDirection; 26 using WebKit::WebTextDirection;
(...skipping 18 matching lines...) Expand all
41 delete this; 45 delete this;
42 } 46 }
43 47
44 virtual WebSize size() { 48 virtual WebSize size() {
45 return size_; 49 return size_;
46 } 50 }
47 51
48 virtual void resize(const WebSize& size) { 52 virtual void resize(const WebSize& size) {
49 size_ = size; 53 size_ = size;
50 WebRect plugin_rect(0, 0, size_.width, size_.height); 54 WebRect plugin_rect(0, 0, size_.width, size_.height);
51 // TODO(piman): transparently scale the plugin instead of resizing it.
52 plugin_->ViewChanged(plugin_rect, plugin_rect); 55 plugin_->ViewChanged(plugin_rect, plugin_rect);
53 widget_->GenerateFullRepaint(); 56 widget_->Invalidate();
54 } 57 }
55 58
56 virtual void layout() { 59 virtual void layout() {
57 } 60 }
58 61
59 virtual void paint(WebCanvas* canvas, const WebRect& rect) { 62 virtual void paint(WebCanvas* canvas, const WebRect& rect) {
60 if (!plugin_) 63 if (!plugin_)
61 return; 64 return;
62 WebRect plugin_rect(0, 0, size_.width, size_.height); 65 WebRect plugin_rect(0, 0, size_.width, size_.height);
63 plugin_->Paint(canvas, plugin_rect, rect); 66 plugin_->Paint(canvas, plugin_rect, rect);
64 } 67 }
65 68
66 virtual void composite(bool finish) { 69 virtual void composite(bool finish) {
67 NOTIMPLEMENTED(); 70 ggl::Context* context = widget_->context();
71 DCHECK(context);
72 gpu::gles2::GLES2Implementation* gl = ggl::GetImplementation(context);
73 unsigned int texture = plugin_->GetBackingTextureId();
74 gl->BindTexture(GL_TEXTURE_2D, texture);
75 gl->DrawArrays(GL_TRIANGLES, 0, 3);
76 ggl::SwapBuffers(context);
68 } 77 }
69 78
70 virtual void themeChanged() { 79 virtual void themeChanged() {
71 NOTIMPLEMENTED(); 80 NOTIMPLEMENTED();
72 } 81 }
73 82
74 virtual bool handleInputEvent(const WebInputEvent& event) { 83 virtual bool handleInputEvent(const WebInputEvent& event) {
75 if (!plugin_) 84 if (!plugin_)
76 return false; 85 return false;
77 return plugin_->HandleInputEvent(event, &cursor_); 86 return plugin_->HandleInputEvent(event, &cursor_);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
112 virtual WebRect caretOrSelectionBounds() { 121 virtual WebRect caretOrSelectionBounds() {
113 NOTIMPLEMENTED(); 122 NOTIMPLEMENTED();
114 return WebRect(); 123 return WebRect();
115 } 124 }
116 125
117 virtual void setTextDirection(WebTextDirection) { 126 virtual void setTextDirection(WebTextDirection) {
118 NOTIMPLEMENTED(); 127 NOTIMPLEMENTED();
119 } 128 }
120 129
121 virtual bool isAcceleratedCompositingActive() const { 130 virtual bool isAcceleratedCompositingActive() const {
122 // TODO(piman): see if supporting accelerated compositing makes sense. 131 return widget_->context() && plugin_ &&
123 return false; 132 (plugin_->GetBackingTextureId() != 0);
124 } 133 }
125 134
126 private: 135 private:
127 webkit::ppapi::PluginInstance* plugin_; 136 webkit::ppapi::PluginInstance* plugin_;
128 RenderWidgetFullscreenPepper* widget_; 137 RenderWidgetFullscreenPepper* widget_;
129 WebSize size_; 138 WebSize size_;
130 WebCursorInfo cursor_; 139 WebCursorInfo cursor_;
131 140
132 DISALLOW_COPY_AND_ASSIGN(PepperWidget); 141 DISALLOW_COPY_AND_ASSIGN(PepperWidget);
133 }; 142 };
134 143
135
136 // A FullscreenContainer that forwards the API calls to the
137 // RenderWidgetFullscreenPepper.
138 class WidgetFullscreenContainer
139 : public webkit::ppapi::FullscreenContainer {
140 public:
141 explicit WidgetFullscreenContainer(RenderWidgetFullscreenPepper* widget)
142 : widget_(widget) {
143 }
144 virtual ~WidgetFullscreenContainer() { }
145
146 virtual void Invalidate() {
147 widget_->GenerateFullRepaint();
148 }
149
150 virtual void InvalidateRect(const WebKit::WebRect& rect) {
151 widget_->didInvalidateRect(rect);
152 }
153
154 virtual void ScrollRect(int dx, int dy, const WebKit::WebRect& rect) {
155 widget_->didScrollRect(dx, dy, rect);
156 }
157
158 virtual void Destroy() {
159 widget_->SendClose();
160 }
161
162 private:
163 RenderWidgetFullscreenPepper* widget_;
164
165 DISALLOW_COPY_AND_ASSIGN(WidgetFullscreenContainer);
166 };
167
168 } // anonymous namespace 144 } // anonymous namespace
169 145
170 // static 146 // static
171 RenderWidgetFullscreenPepper* RenderWidgetFullscreenPepper::Create( 147 RenderWidgetFullscreenPepper* RenderWidgetFullscreenPepper::Create(
172 int32 opener_id, RenderThreadBase* render_thread, 148 int32 opener_id, RenderThreadBase* render_thread,
173 webkit::ppapi::PluginInstance* plugin) { 149 webkit::ppapi::PluginInstance* plugin) {
174 DCHECK_NE(MSG_ROUTING_NONE, opener_id); 150 DCHECK_NE(MSG_ROUTING_NONE, opener_id);
175 scoped_refptr<RenderWidgetFullscreenPepper> widget( 151 scoped_refptr<RenderWidgetFullscreenPepper> widget(
176 new RenderWidgetFullscreenPepper(render_thread, plugin)); 152 new RenderWidgetFullscreenPepper(render_thread, plugin));
177 widget->Init(opener_id); 153 widget->Init(opener_id);
178 return widget.release(); 154 return widget.release();
179 } 155 }
180 156
181 RenderWidgetFullscreenPepper::RenderWidgetFullscreenPepper( 157 RenderWidgetFullscreenPepper::RenderWidgetFullscreenPepper(
182 RenderThreadBase* render_thread, 158 RenderThreadBase* render_thread,
183 webkit::ppapi::PluginInstance* plugin) 159 webkit::ppapi::PluginInstance* plugin)
184 : RenderWidgetFullscreen(render_thread, WebKit::WebPopupTypeSelect), 160 : RenderWidgetFullscreen(render_thread, WebKit::WebPopupTypeSelect),
185 plugin_(plugin), 161 plugin_(plugin),
186 ALLOW_THIS_IN_INITIALIZER_LIST( 162 #if defined(OS_MACOSX)
187 container_(new WidgetFullscreenContainer(this))) { 163 plugin_handle_(NULL),
164 #endif
165 context_(NULL) {
188 } 166 }
189 167
190 RenderWidgetFullscreenPepper::~RenderWidgetFullscreenPepper() { 168 RenderWidgetFullscreenPepper::~RenderWidgetFullscreenPepper() {
169 if (context_) {
170 ggl::DestroyContext(context_);
171 #if defined(OS_MACOSX)
172 if (plugin_handle_) {
173 Send(new ViewHostMsg_DestroyFakePluginWindowHandle(routing_id(),
174 plugin_handle_));
175 }
176 #endif
177 }
191 } 178 }
192 179
193 WebWidget* RenderWidgetFullscreenPepper::CreateWebWidget() { 180 void RenderWidgetFullscreenPepper::Invalidate() {
194 return new PepperWidget(plugin_, this); 181 InvalidateRect(gfx::Rect(size_.width(), size_.height()));
195 } 182 }
196 183
197 void RenderWidgetFullscreenPepper::Close() { 184 void RenderWidgetFullscreenPepper::InvalidateRect(const WebKit::WebRect& rect) {
198 // If the fullscreen window is closed (e.g. user pressed escape), reset to 185 if (CheckCompositing()) {
199 // normal mode. 186 scheduleComposite();
200 if (plugin_) 187 } else {
201 plugin_->SetFullscreen(false); 188 didInvalidateRect(rect);
189 }
190 }
191
192 void RenderWidgetFullscreenPepper::ScrollRect(
193 int dx, int dy, const WebKit::WebRect& rect) {
194 if (CheckCompositing()) {
195 scheduleComposite();
196 } else {
197 didScrollRect(dx, dy, rect);
198 }
199 }
200
201 void RenderWidgetFullscreenPepper::Destroy() {
202 // This function is called by the plugin instance as it's going away, so reset
203 // plugin_ to NULL to avoid calling into a dangling pointer e.g. on Close().
204 plugin_ = NULL;
205 Send(new ViewHostMsg_Close(routing_id_));
206 }
207
208 webkit::ppapi::PluginDelegate::PlatformContext3D*
209 RenderWidgetFullscreenPepper::CreateContext3D() {
210 if (!context_) {
211 CreateContext();
212 }
213 if (!context_)
214 return NULL;
215 return new PlatformContext3DImpl(context_);
202 } 216 }
203 217
204 void RenderWidgetFullscreenPepper::DidInitiatePaint() { 218 void RenderWidgetFullscreenPepper::DidInitiatePaint() {
205 if (plugin_) 219 if (plugin_)
206 plugin_->ViewInitiatedPaint(); 220 plugin_->ViewInitiatedPaint();
207 } 221 }
208 222
209 void RenderWidgetFullscreenPepper::DidFlushPaint() { 223 void RenderWidgetFullscreenPepper::DidFlushPaint() {
210 if (plugin_) 224 if (plugin_)
211 plugin_->ViewFlushedPaint(); 225 plugin_->ViewFlushedPaint();
212 } 226 }
213 227
214 void RenderWidgetFullscreenPepper::SendClose() { 228 void RenderWidgetFullscreenPepper::Close() {
215 // This function is called by the plugin instance as it's going away, so reset 229 // If the fullscreen window is closed (e.g. user pressed escape), reset to
216 // plugin_ to NULL to avoid calling into a dangling pointer e.g. on Close(). 230 // normal mode.
217 plugin_ = NULL; 231 if (plugin_)
218 Send(new ViewHostMsg_Close(routing_id_)); 232 plugin_->SetFullscreen(false);
219 }
220
221 void RenderWidgetFullscreenPepper::GenerateFullRepaint() {
222 didInvalidateRect(gfx::Rect(size_.width(), size_.height()));
223 } 233 }
224 234
225 webkit::ppapi::PluginInstance* 235 webkit::ppapi::PluginInstance*
226 RenderWidgetFullscreenPepper::GetBitmapForOptimizedPluginPaint( 236 RenderWidgetFullscreenPepper::GetBitmapForOptimizedPluginPaint(
227 const gfx::Rect& paint_bounds, 237 const gfx::Rect& paint_bounds,
228 TransportDIB** dib, 238 TransportDIB** dib,
229 gfx::Rect* location, 239 gfx::Rect* location,
230 gfx::Rect* clip) { 240 gfx::Rect* clip) {
231 if (plugin_ && 241 if (plugin_ &&
232 plugin_->GetBitmapForOptimizedPluginPaint(paint_bounds, dib, 242 plugin_->GetBitmapForOptimizedPluginPaint(paint_bounds, dib,
233 location, clip)) 243 location, clip))
234 return plugin_; 244 return plugin_;
235 return NULL; 245 return NULL;
236 } 246 }
247
248 void RenderWidgetFullscreenPepper::OnResize(const gfx::Size& size,
249 const gfx::Rect& resizer_rect) {
250 if (context_) {
251 #if defined(OS_MACOSX)
252 ggl::ResizeOnscreenContext(context_, size);
253 #else
254 gpu::gles2::GLES2Implementation* gl = ggl::GetImplementation(context_);
255 gl->ResizeCHROMIUM(size.width(), size.height());
256 #endif
257 gl->Viewport(0, 0, size.width(), size.height());
258 }
259 RenderWidget::OnResize(size, resizer_rect);
260 }
261
262 WebWidget* RenderWidgetFullscreenPepper::CreateWebWidget() {
263 return new PepperWidget(plugin_, this);
264 }
265
266 void RenderWidgetFullscreenPepper::CreateContext() {
267 DCHECK(!context_);
268 RenderThread* render_thread = RenderThread::current();
269 DCHECK(render_thread);
270 GpuChannelHost* host = render_thread->EstablishGpuChannelSync();
271 if (!host)
272 return;
273 gfx::NativeViewId view_id;
274 #if !defined(OS_MACOSX)
275 view_id = host_window();
276 #else
277 Send(new ViewHostMsg_AllocateFakePluginWindowHandle(
278 routing_id(), true, true, &plugin_handle_));
279 if (!plugin_handle_)
280 return;
281 view_id = static_cast<gfx::NativeViewId>(plugin_handle_);
282 #endif
283 const int32 attribs[] = {
284 ggl::GGL_ALPHA_SIZE, 8,
285 ggl::GGL_DEPTH_SIZE, 0,
286 ggl::GGL_STENCIL_SIZE, 0,
287 ggl::GGL_SAMPLES, 0,
288 ggl::GGL_SAMPLE_BUFFERS, 0,
289 ggl::GGL_NONE,
290 };
291 context_ = ggl::CreateViewContext(
292 host,
293 view_id,
294 routing_id(),
295 "GL_OES_packed_depth_stencil GL_OES_depth24",
296 attribs);
297 if (!InitContext()) {
298 ggl::DestroyContext(context_);
299 context_ = NULL;
300 }
301 if (!context_) {
302 #if defined(OS_MACOSX)
303 Send(new ViewHostMsg_DestroyFakePluginWindowHandle(routing_id(),
304 plugin_handle_));
305 plugin_handle_ = NULL;
306 #endif
307 return;
308 }
309 ggl::SetSwapBuffersCallback(
310 context_,
311 NewCallback(this, &RenderWidgetFullscreenPepper::DidFlushPaint));
312 }
313
314 namespace {
315
316 const char kVertexShader[] =
317 "attribute vec2 in_tex_coord;\n"
318 "varying vec2 tex_coord;\n"
319 "void main() {\n"
320 " gl_Position = vec4(in_tex_coord.x * 2. - 1.,\n"
321 " in_tex_coord.y * 2. - 1.,\n"
322 " 0.,\n"
323 " 1.);\n"
324 " tex_coord = vec2(in_tex_coord.x, 1. - in_tex_coord.y);\n"
325 "}\n";
326
327 const char kFragmentShader[] =
328 "precision mediump float;\n"
329 "varying vec2 tex_coord;\n"
330 "uniform sampler2D in_texture;\n"
331 "void main() {\n"
332 " gl_FragColor = texture2D(in_texture, tex_coord);\n"
333 "}\n";
334
335 GLuint CreateShaderFromSource(gpu::gles2::GLES2Implementation* gl,
336 GLenum type,
337 const char* source) {
338 GLuint shader = gl->CreateShader(type);
339 gl->ShaderSource(shader, 1, &source, NULL);
340 gl->CompileShader(shader);
341 int status;
342 gl->GetShaderiv(shader, GL_COMPILE_STATUS, &status);
343 if (!status) {
344 int size = 0;
345 gl->GetShaderiv(shader, GL_INFO_LOG_LENGTH, &size);
346 scoped_array<char> log(new char[size]);
347 gl->GetShaderInfoLog(shader, size, NULL, log.get());
348 DLOG(ERROR) << "Compilation failed: " << log.get();
349 gl->DeleteShader(shader);
350 shader = 0;
351 }
352 return shader;
353 }
354
355 float kTexCoords[] = {
apatrick 2011/01/06 02:59:31 const float?
piman 2011/01/06 04:27:46 Done.
356 0.f, 0.f,
357 0.f, 2.f,
358 2.f, 0.f,
359 };
360
361 } // anonymous namespace
362
363 bool RenderWidgetFullscreenPepper::InitContext() {
364 gpu::gles2::GLES2Implementation* gl = ggl::GetImplementation(context_);
365 program_ = gl->CreateProgram();
apatrick 2011/01/06 02:59:31 You're relying on the context being destroyed to d
piman 2011/01/06 04:27:46 Done. I was relying on the context destruction, a
366
367 GLuint vertex_shader =
368 CreateShaderFromSource(gl, GL_VERTEX_SHADER, kVertexShader);
369 if (!vertex_shader)
370 return false;
371 gl->AttachShader(program_, vertex_shader);
372 gl->DeleteShader(vertex_shader);
373
374 GLuint fragment_shader =
375 CreateShaderFromSource(gl, GL_FRAGMENT_SHADER, kFragmentShader);
376 if (!fragment_shader)
377 return false;
378 gl->AttachShader(program_, fragment_shader);
379 gl->DeleteShader(fragment_shader);
380
381 gl->BindAttribLocation(program_, 0, "in_tex_coord");
382 gl->LinkProgram(program_);
383 int status;
384 gl->GetProgramiv(program_, GL_LINK_STATUS, &status);
385 if (!status) {
386 int size = 0;
387 gl->GetProgramiv(program_, GL_INFO_LOG_LENGTH, &size);
388 scoped_array<char> log(new char[size]);
389 gl->GetProgramInfoLog(program_, size, NULL, log.get());
390 DLOG(ERROR) << "Link failed: " << log.get();
391 return false;
392 }
393 gl->UseProgram(program_);
394 int texture_location = gl->GetUniformLocation(program_, "in_texture");
395 gl->Uniform1i(texture_location, 0);
396
397 gl->GenBuffers(1, &buffer_);
398 gl->BindBuffer(GL_ARRAY_BUFFER, buffer_);
399 gl->BufferData(GL_ARRAY_BUFFER,
400 sizeof(kTexCoords),
401 kTexCoords,
402 GL_STATIC_DRAW);
403 gl->VertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, NULL);
404 gl->EnableVertexAttribArray(0);
405 return true;
406 }
407
408 bool RenderWidgetFullscreenPepper::CheckCompositing() {
409 bool compositing = webwidget_->isAcceleratedCompositingActive();
410 if (compositing != is_accelerated_compositing_active_) {
411 didActivateAcceleratedCompositing(compositing);
412 }
413 return compositing;
414 }
OLDNEW
« no previous file with comments | « chrome/renderer/render_widget_fullscreen_pepper.h ('k') | webkit/plugins/ppapi/fullscreen_container.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698