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

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: style 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),
166 buffer_(0),
167 program_(0) {
188 } 168 }
189 169
190 RenderWidgetFullscreenPepper::~RenderWidgetFullscreenPepper() { 170 RenderWidgetFullscreenPepper::~RenderWidgetFullscreenPepper() {
171 DestroyContext();
191 } 172 }
192 173
193 WebWidget* RenderWidgetFullscreenPepper::CreateWebWidget() { 174 void RenderWidgetFullscreenPepper::Invalidate() {
194 return new PepperWidget(plugin_, this); 175 InvalidateRect(gfx::Rect(size_.width(), size_.height()));
195 } 176 }
196 177
197 void RenderWidgetFullscreenPepper::Close() { 178 void RenderWidgetFullscreenPepper::InvalidateRect(const WebKit::WebRect& rect) {
198 // If the fullscreen window is closed (e.g. user pressed escape), reset to 179 if (CheckCompositing()) {
199 // normal mode. 180 scheduleComposite();
200 if (plugin_) 181 } else {
201 plugin_->SetFullscreen(false); 182 didInvalidateRect(rect);
183 }
184 }
185
186 void RenderWidgetFullscreenPepper::ScrollRect(
187 int dx, int dy, const WebKit::WebRect& rect) {
188 if (CheckCompositing()) {
189 scheduleComposite();
190 } else {
191 didScrollRect(dx, dy, rect);
192 }
193 }
194
195 void RenderWidgetFullscreenPepper::Destroy() {
196 // This function is called by the plugin instance as it's going away, so reset
197 // plugin_ to NULL to avoid calling into a dangling pointer e.g. on Close().
198 plugin_ = NULL;
199 Send(new ViewHostMsg_Close(routing_id_));
200 }
201
202 webkit::ppapi::PluginDelegate::PlatformContext3D*
203 RenderWidgetFullscreenPepper::CreateContext3D() {
204 if (!context_) {
205 CreateContext();
206 }
207 if (!context_)
208 return NULL;
209 return new PlatformContext3DImpl(context_);
202 } 210 }
203 211
204 void RenderWidgetFullscreenPepper::DidInitiatePaint() { 212 void RenderWidgetFullscreenPepper::DidInitiatePaint() {
205 if (plugin_) 213 if (plugin_)
206 plugin_->ViewInitiatedPaint(); 214 plugin_->ViewInitiatedPaint();
207 } 215 }
208 216
209 void RenderWidgetFullscreenPepper::DidFlushPaint() { 217 void RenderWidgetFullscreenPepper::DidFlushPaint() {
210 if (plugin_) 218 if (plugin_)
211 plugin_->ViewFlushedPaint(); 219 plugin_->ViewFlushedPaint();
212 } 220 }
213 221
214 void RenderWidgetFullscreenPepper::SendClose() { 222 void RenderWidgetFullscreenPepper::Close() {
215 // This function is called by the plugin instance as it's going away, so reset 223 // 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(). 224 // normal mode.
217 plugin_ = NULL; 225 if (plugin_)
218 Send(new ViewHostMsg_Close(routing_id_)); 226 plugin_->SetFullscreen(false);
219 }
220
221 void RenderWidgetFullscreenPepper::GenerateFullRepaint() {
222 didInvalidateRect(gfx::Rect(size_.width(), size_.height()));
223 } 227 }
224 228
225 webkit::ppapi::PluginInstance* 229 webkit::ppapi::PluginInstance*
226 RenderWidgetFullscreenPepper::GetBitmapForOptimizedPluginPaint( 230 RenderWidgetFullscreenPepper::GetBitmapForOptimizedPluginPaint(
227 const gfx::Rect& paint_bounds, 231 const gfx::Rect& paint_bounds,
228 TransportDIB** dib, 232 TransportDIB** dib,
229 gfx::Rect* location, 233 gfx::Rect* location,
230 gfx::Rect* clip) { 234 gfx::Rect* clip) {
231 if (plugin_ && 235 if (plugin_ &&
232 plugin_->GetBitmapForOptimizedPluginPaint(paint_bounds, dib, 236 plugin_->GetBitmapForOptimizedPluginPaint(paint_bounds, dib,
233 location, clip)) 237 location, clip))
234 return plugin_; 238 return plugin_;
235 return NULL; 239 return NULL;
236 } 240 }
241
242 void RenderWidgetFullscreenPepper::OnResize(const gfx::Size& size,
243 const gfx::Rect& resizer_rect) {
244 if (context_) {
245 #if defined(OS_MACOSX)
246 ggl::ResizeOnscreenContext(context_, size);
247 #else
248 gpu::gles2::GLES2Implementation* gl = ggl::GetImplementation(context_);
249 gl->ResizeCHROMIUM(size.width(), size.height());
250 #endif
251 gl->Viewport(0, 0, size.width(), size.height());
252 }
253 RenderWidget::OnResize(size, resizer_rect);
254 }
255
256 WebWidget* RenderWidgetFullscreenPepper::CreateWebWidget() {
257 return new PepperWidget(plugin_, this);
258 }
259
260 void RenderWidgetFullscreenPepper::CreateContext() {
261 DCHECK(!context_);
262 RenderThread* render_thread = RenderThread::current();
263 DCHECK(render_thread);
264 GpuChannelHost* host = render_thread->EstablishGpuChannelSync();
265 if (!host)
266 return;
267 gfx::NativeViewId view_id;
268 #if !defined(OS_MACOSX)
269 view_id = host_window();
270 #else
271 Send(new ViewHostMsg_AllocateFakePluginWindowHandle(
272 routing_id(), true, true, &plugin_handle_));
273 if (!plugin_handle_)
274 return;
275 view_id = static_cast<gfx::NativeViewId>(plugin_handle_);
276 #endif
277 const int32 attribs[] = {
278 ggl::GGL_ALPHA_SIZE, 8,
279 ggl::GGL_DEPTH_SIZE, 0,
280 ggl::GGL_STENCIL_SIZE, 0,
281 ggl::GGL_SAMPLES, 0,
282 ggl::GGL_SAMPLE_BUFFERS, 0,
283 ggl::GGL_NONE,
284 };
285 context_ = ggl::CreateViewContext(
286 host,
287 view_id,
288 routing_id(),
289 "GL_OES_packed_depth_stencil GL_OES_depth24",
290 attribs);
291 if (!context_ || !InitContext()) {
292 DestroyContext();
293 return;
294 }
295 ggl::SetSwapBuffersCallback(
296 context_,
297 NewCallback(this, &RenderWidgetFullscreenPepper::DidFlushPaint));
298 }
299
300 void RenderWidgetFullscreenPepper::DestroyContext() {
301 if (context_) {
302 gpu::gles2::GLES2Implementation* gl = ggl::GetImplementation(context_);
303 if (program_) {
304 gl->DeleteProgram(program_);
305 program_ = 0;
306 }
307 if (buffer_) {
308 gl->DeleteBuffers(1, &buffer_);
309 buffer_ = 0;
310 }
311 ggl::DestroyContext(context_);
312 context_ = NULL;
313 }
314 #if defined(OS_MACOSX)
315 if (plugin_handle_) {
316 Send(new ViewHostMsg_DestroyFakePluginWindowHandle(routing_id(),
317 plugin_handle_));
318 plugin_handle_ = NULL;
319 }
320 #endif
321 }
322
323 namespace {
324
325 const char kVertexShader[] =
326 "attribute vec2 in_tex_coord;\n"
327 "varying vec2 tex_coord;\n"
328 "void main() {\n"
329 " gl_Position = vec4(in_tex_coord.x * 2. - 1.,\n"
330 " in_tex_coord.y * 2. - 1.,\n"
331 " 0.,\n"
332 " 1.);\n"
333 " tex_coord = vec2(in_tex_coord.x, 1. - in_tex_coord.y);\n"
334 "}\n";
335
336 const char kFragmentShader[] =
337 "precision mediump float;\n"
338 "varying vec2 tex_coord;\n"
339 "uniform sampler2D in_texture;\n"
340 "void main() {\n"
341 " gl_FragColor = texture2D(in_texture, tex_coord);\n"
342 "}\n";
343
344 GLuint CreateShaderFromSource(gpu::gles2::GLES2Implementation* gl,
345 GLenum type,
346 const char* source) {
347 GLuint shader = gl->CreateShader(type);
348 gl->ShaderSource(shader, 1, &source, NULL);
349 gl->CompileShader(shader);
350 int status;
351 gl->GetShaderiv(shader, GL_COMPILE_STATUS, &status);
352 if (!status) {
353 int size = 0;
354 gl->GetShaderiv(shader, GL_INFO_LOG_LENGTH, &size);
355 scoped_array<char> log(new char[size]);
356 gl->GetShaderInfoLog(shader, size, NULL, log.get());
357 DLOG(ERROR) << "Compilation failed: " << log.get();
358 gl->DeleteShader(shader);
359 shader = 0;
360 }
361 return shader;
362 }
363
364 const float kTexCoords[] = {
365 0.f, 0.f,
366 0.f, 2.f,
367 2.f, 0.f,
368 };
369
370 } // anonymous namespace
371
372 bool RenderWidgetFullscreenPepper::InitContext() {
373 gpu::gles2::GLES2Implementation* gl = ggl::GetImplementation(context_);
374 program_ = gl->CreateProgram();
375
376 GLuint vertex_shader =
377 CreateShaderFromSource(gl, GL_VERTEX_SHADER, kVertexShader);
378 if (!vertex_shader)
379 return false;
380 gl->AttachShader(program_, vertex_shader);
381 gl->DeleteShader(vertex_shader);
382
383 GLuint fragment_shader =
384 CreateShaderFromSource(gl, GL_FRAGMENT_SHADER, kFragmentShader);
385 if (!fragment_shader)
386 return false;
387 gl->AttachShader(program_, fragment_shader);
388 gl->DeleteShader(fragment_shader);
389
390 gl->BindAttribLocation(program_, 0, "in_tex_coord");
391 gl->LinkProgram(program_);
392 int status;
393 gl->GetProgramiv(program_, GL_LINK_STATUS, &status);
394 if (!status) {
395 int size = 0;
396 gl->GetProgramiv(program_, GL_INFO_LOG_LENGTH, &size);
397 scoped_array<char> log(new char[size]);
398 gl->GetProgramInfoLog(program_, size, NULL, log.get());
399 DLOG(ERROR) << "Link failed: " << log.get();
400 return false;
401 }
402 gl->UseProgram(program_);
403 int texture_location = gl->GetUniformLocation(program_, "in_texture");
404 gl->Uniform1i(texture_location, 0);
405
406 gl->GenBuffers(1, &buffer_);
407 gl->BindBuffer(GL_ARRAY_BUFFER, buffer_);
408 gl->BufferData(GL_ARRAY_BUFFER,
409 sizeof(kTexCoords),
410 kTexCoords,
411 GL_STATIC_DRAW);
412 gl->VertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, NULL);
413 gl->EnableVertexAttribArray(0);
414 return true;
415 }
416
417 bool RenderWidgetFullscreenPepper::CheckCompositing() {
418 bool compositing = webwidget_->isAcceleratedCompositingActive();
419 if (compositing != is_accelerated_compositing_active_) {
420 didActivateAcceleratedCompositing(compositing);
421 }
422 return compositing;
423 }
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