| Index: chrome/renderer/render_widget_fullscreen_pepper.cc
|
| diff --git a/chrome/renderer/render_widget_fullscreen_pepper.cc b/chrome/renderer/render_widget_fullscreen_pepper.cc
|
| index 539da366e7e82136e76bfda2441e34161b2fee89..27372b3a7893e08206bac88c542ccc67793f39a9 100644
|
| --- a/chrome/renderer/render_widget_fullscreen_pepper.cc
|
| +++ b/chrome/renderer/render_widget_fullscreen_pepper.cc
|
| @@ -5,11 +5,15 @@
|
| #include "chrome/renderer/render_widget_fullscreen_pepper.h"
|
|
|
| #include "chrome/common/render_messages.h"
|
| +#include "chrome/renderer/ggl/ggl.h"
|
| +#include "chrome/renderer/gpu_channel_host.h"
|
| +#include "chrome/renderer/pepper_platform_context_3d_impl.h"
|
| #include "chrome/renderer/render_thread.h"
|
| +#include "gpu/command_buffer/client/gles2_implementation.h"
|
| #include "third_party/WebKit/WebKit/chromium/public/WebCursorInfo.h"
|
| #include "third_party/WebKit/WebKit/chromium/public/WebSize.h"
|
| #include "third_party/WebKit/WebKit/chromium/public/WebWidget.h"
|
| -#include "webkit/plugins/ppapi/fullscreen_container.h"
|
| +#include "webkit/plugins/ppapi/plugin_delegate.h"
|
| #include "webkit/plugins/ppapi/ppapi_plugin_instance.h"
|
|
|
| using WebKit::WebCanvas;
|
| @@ -48,9 +52,8 @@ class PepperWidget : public WebWidget {
|
| virtual void resize(const WebSize& size) {
|
| size_ = size;
|
| WebRect plugin_rect(0, 0, size_.width, size_.height);
|
| - // TODO(piman): transparently scale the plugin instead of resizing it.
|
| plugin_->ViewChanged(plugin_rect, plugin_rect);
|
| - widget_->GenerateFullRepaint();
|
| + widget_->Invalidate();
|
| }
|
|
|
| virtual void layout() {
|
| @@ -64,7 +67,13 @@ class PepperWidget : public WebWidget {
|
| }
|
|
|
| virtual void composite(bool finish) {
|
| - NOTIMPLEMENTED();
|
| + ggl::Context* context = widget_->context();
|
| + DCHECK(context);
|
| + gpu::gles2::GLES2Implementation* gl = ggl::GetImplementation(context);
|
| + unsigned int texture = plugin_->GetBackingTextureId();
|
| + gl->BindTexture(GL_TEXTURE_2D, texture);
|
| + gl->DrawArrays(GL_TRIANGLES, 0, 3);
|
| + ggl::SwapBuffers(context);
|
| }
|
|
|
| virtual void themeChanged() {
|
| @@ -119,8 +128,8 @@ class PepperWidget : public WebWidget {
|
| }
|
|
|
| virtual bool isAcceleratedCompositingActive() const {
|
| - // TODO(piman): see if supporting accelerated compositing makes sense.
|
| - return false;
|
| + return widget_->context() && plugin_ &&
|
| + (plugin_->GetBackingTextureId() != 0);
|
| }
|
|
|
| private:
|
| @@ -132,39 +141,6 @@ class PepperWidget : public WebWidget {
|
| DISALLOW_COPY_AND_ASSIGN(PepperWidget);
|
| };
|
|
|
| -
|
| -// A FullscreenContainer that forwards the API calls to the
|
| -// RenderWidgetFullscreenPepper.
|
| -class WidgetFullscreenContainer
|
| - : public webkit::ppapi::FullscreenContainer {
|
| - public:
|
| - explicit WidgetFullscreenContainer(RenderWidgetFullscreenPepper* widget)
|
| - : widget_(widget) {
|
| - }
|
| - virtual ~WidgetFullscreenContainer() { }
|
| -
|
| - virtual void Invalidate() {
|
| - widget_->GenerateFullRepaint();
|
| - }
|
| -
|
| - virtual void InvalidateRect(const WebKit::WebRect& rect) {
|
| - widget_->didInvalidateRect(rect);
|
| - }
|
| -
|
| - virtual void ScrollRect(int dx, int dy, const WebKit::WebRect& rect) {
|
| - widget_->didScrollRect(dx, dy, rect);
|
| - }
|
| -
|
| - virtual void Destroy() {
|
| - widget_->SendClose();
|
| - }
|
| -
|
| - private:
|
| - RenderWidgetFullscreenPepper* widget_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(WidgetFullscreenContainer);
|
| -};
|
| -
|
| } // anonymous namespace
|
|
|
| // static
|
| @@ -183,22 +159,54 @@ RenderWidgetFullscreenPepper::RenderWidgetFullscreenPepper(
|
| webkit::ppapi::PluginInstance* plugin)
|
| : RenderWidgetFullscreen(render_thread, WebKit::WebPopupTypeSelect),
|
| plugin_(plugin),
|
| - ALLOW_THIS_IN_INITIALIZER_LIST(
|
| - container_(new WidgetFullscreenContainer(this))) {
|
| +#if defined(OS_MACOSX)
|
| + plugin_handle_(NULL),
|
| +#endif
|
| + context_(NULL),
|
| + buffer_(0),
|
| + program_(0) {
|
| }
|
|
|
| RenderWidgetFullscreenPepper::~RenderWidgetFullscreenPepper() {
|
| + DestroyContext();
|
| }
|
|
|
| -WebWidget* RenderWidgetFullscreenPepper::CreateWebWidget() {
|
| - return new PepperWidget(plugin_, this);
|
| +void RenderWidgetFullscreenPepper::Invalidate() {
|
| + InvalidateRect(gfx::Rect(size_.width(), size_.height()));
|
| }
|
|
|
| -void RenderWidgetFullscreenPepper::Close() {
|
| - // If the fullscreen window is closed (e.g. user pressed escape), reset to
|
| - // normal mode.
|
| - if (plugin_)
|
| - plugin_->SetFullscreen(false);
|
| +void RenderWidgetFullscreenPepper::InvalidateRect(const WebKit::WebRect& rect) {
|
| + if (CheckCompositing()) {
|
| + scheduleComposite();
|
| + } else {
|
| + didInvalidateRect(rect);
|
| + }
|
| +}
|
| +
|
| +void RenderWidgetFullscreenPepper::ScrollRect(
|
| + int dx, int dy, const WebKit::WebRect& rect) {
|
| + if (CheckCompositing()) {
|
| + scheduleComposite();
|
| + } else {
|
| + didScrollRect(dx, dy, rect);
|
| + }
|
| +}
|
| +
|
| +void RenderWidgetFullscreenPepper::Destroy() {
|
| + // This function is called by the plugin instance as it's going away, so reset
|
| + // plugin_ to NULL to avoid calling into a dangling pointer e.g. on Close().
|
| + plugin_ = NULL;
|
| + Send(new ViewHostMsg_Close(routing_id_));
|
| +}
|
| +
|
| +webkit::ppapi::PluginDelegate::PlatformContext3D*
|
| +RenderWidgetFullscreenPepper::CreateContext3D() {
|
| + if (!context_) {
|
| + CreateContext();
|
| + }
|
| + if (!context_)
|
| + return NULL;
|
| + return new PlatformContext3DImpl(context_);
|
| }
|
|
|
| void RenderWidgetFullscreenPepper::DidInitiatePaint() {
|
| @@ -211,15 +219,11 @@ void RenderWidgetFullscreenPepper::DidFlushPaint() {
|
| plugin_->ViewFlushedPaint();
|
| }
|
|
|
| -void RenderWidgetFullscreenPepper::SendClose() {
|
| - // This function is called by the plugin instance as it's going away, so reset
|
| - // plugin_ to NULL to avoid calling into a dangling pointer e.g. on Close().
|
| - plugin_ = NULL;
|
| - Send(new ViewHostMsg_Close(routing_id_));
|
| -}
|
| -
|
| -void RenderWidgetFullscreenPepper::GenerateFullRepaint() {
|
| - didInvalidateRect(gfx::Rect(size_.width(), size_.height()));
|
| +void RenderWidgetFullscreenPepper::Close() {
|
| + // If the fullscreen window is closed (e.g. user pressed escape), reset to
|
| + // normal mode.
|
| + if (plugin_)
|
| + plugin_->SetFullscreen(false);
|
| }
|
|
|
| webkit::ppapi::PluginInstance*
|
| @@ -234,3 +238,186 @@ RenderWidgetFullscreenPepper::GetBitmapForOptimizedPluginPaint(
|
| return plugin_;
|
| return NULL;
|
| }
|
| +
|
| +void RenderWidgetFullscreenPepper::OnResize(const gfx::Size& size,
|
| + const gfx::Rect& resizer_rect) {
|
| + if (context_) {
|
| +#if defined(OS_MACOSX)
|
| + ggl::ResizeOnscreenContext(context_, size);
|
| +#else
|
| + gpu::gles2::GLES2Implementation* gl = ggl::GetImplementation(context_);
|
| + gl->ResizeCHROMIUM(size.width(), size.height());
|
| +#endif
|
| + gl->Viewport(0, 0, size.width(), size.height());
|
| + }
|
| + RenderWidget::OnResize(size, resizer_rect);
|
| +}
|
| +
|
| +WebWidget* RenderWidgetFullscreenPepper::CreateWebWidget() {
|
| + return new PepperWidget(plugin_, this);
|
| +}
|
| +
|
| +void RenderWidgetFullscreenPepper::CreateContext() {
|
| + DCHECK(!context_);
|
| + RenderThread* render_thread = RenderThread::current();
|
| + DCHECK(render_thread);
|
| + GpuChannelHost* host = render_thread->EstablishGpuChannelSync();
|
| + if (!host)
|
| + return;
|
| + gfx::NativeViewId view_id;
|
| +#if !defined(OS_MACOSX)
|
| + view_id = host_window();
|
| +#else
|
| + Send(new ViewHostMsg_AllocateFakePluginWindowHandle(
|
| + routing_id(), true, true, &plugin_handle_));
|
| + if (!plugin_handle_)
|
| + return;
|
| + view_id = static_cast<gfx::NativeViewId>(plugin_handle_);
|
| +#endif
|
| + const int32 attribs[] = {
|
| + ggl::GGL_ALPHA_SIZE, 8,
|
| + ggl::GGL_DEPTH_SIZE, 0,
|
| + ggl::GGL_STENCIL_SIZE, 0,
|
| + ggl::GGL_SAMPLES, 0,
|
| + ggl::GGL_SAMPLE_BUFFERS, 0,
|
| + ggl::GGL_NONE,
|
| + };
|
| + context_ = ggl::CreateViewContext(
|
| + host,
|
| + view_id,
|
| + routing_id(),
|
| + "GL_OES_packed_depth_stencil GL_OES_depth24",
|
| + attribs);
|
| + if (!context_ || !InitContext()) {
|
| + DestroyContext();
|
| + return;
|
| + }
|
| + ggl::SetSwapBuffersCallback(
|
| + context_,
|
| + NewCallback(this, &RenderWidgetFullscreenPepper::DidFlushPaint));
|
| +}
|
| +
|
| +void RenderWidgetFullscreenPepper::DestroyContext() {
|
| + if (context_) {
|
| + gpu::gles2::GLES2Implementation* gl = ggl::GetImplementation(context_);
|
| + if (program_) {
|
| + gl->DeleteProgram(program_);
|
| + program_ = 0;
|
| + }
|
| + if (buffer_) {
|
| + gl->DeleteBuffers(1, &buffer_);
|
| + buffer_ = 0;
|
| + }
|
| + ggl::DestroyContext(context_);
|
| + context_ = NULL;
|
| + }
|
| +#if defined(OS_MACOSX)
|
| + if (plugin_handle_) {
|
| + Send(new ViewHostMsg_DestroyFakePluginWindowHandle(routing_id(),
|
| + plugin_handle_));
|
| + plugin_handle_ = NULL;
|
| + }
|
| +#endif
|
| +}
|
| +
|
| +namespace {
|
| +
|
| +const char kVertexShader[] =
|
| + "attribute vec2 in_tex_coord;\n"
|
| + "varying vec2 tex_coord;\n"
|
| + "void main() {\n"
|
| + " gl_Position = vec4(in_tex_coord.x * 2. - 1.,\n"
|
| + " in_tex_coord.y * 2. - 1.,\n"
|
| + " 0.,\n"
|
| + " 1.);\n"
|
| + " tex_coord = vec2(in_tex_coord.x, 1. - in_tex_coord.y);\n"
|
| + "}\n";
|
| +
|
| +const char kFragmentShader[] =
|
| + "precision mediump float;\n"
|
| + "varying vec2 tex_coord;\n"
|
| + "uniform sampler2D in_texture;\n"
|
| + "void main() {\n"
|
| + " gl_FragColor = texture2D(in_texture, tex_coord);\n"
|
| + "}\n";
|
| +
|
| +GLuint CreateShaderFromSource(gpu::gles2::GLES2Implementation* gl,
|
| + GLenum type,
|
| + const char* source) {
|
| + GLuint shader = gl->CreateShader(type);
|
| + gl->ShaderSource(shader, 1, &source, NULL);
|
| + gl->CompileShader(shader);
|
| + int status;
|
| + gl->GetShaderiv(shader, GL_COMPILE_STATUS, &status);
|
| + if (!status) {
|
| + int size = 0;
|
| + gl->GetShaderiv(shader, GL_INFO_LOG_LENGTH, &size);
|
| + scoped_array<char> log(new char[size]);
|
| + gl->GetShaderInfoLog(shader, size, NULL, log.get());
|
| + DLOG(ERROR) << "Compilation failed: " << log.get();
|
| + gl->DeleteShader(shader);
|
| + shader = 0;
|
| + }
|
| + return shader;
|
| +}
|
| +
|
| +const float kTexCoords[] = {
|
| + 0.f, 0.f,
|
| + 0.f, 2.f,
|
| + 2.f, 0.f,
|
| +};
|
| +
|
| +} // anonymous namespace
|
| +
|
| +bool RenderWidgetFullscreenPepper::InitContext() {
|
| + gpu::gles2::GLES2Implementation* gl = ggl::GetImplementation(context_);
|
| + program_ = gl->CreateProgram();
|
| +
|
| + GLuint vertex_shader =
|
| + CreateShaderFromSource(gl, GL_VERTEX_SHADER, kVertexShader);
|
| + if (!vertex_shader)
|
| + return false;
|
| + gl->AttachShader(program_, vertex_shader);
|
| + gl->DeleteShader(vertex_shader);
|
| +
|
| + GLuint fragment_shader =
|
| + CreateShaderFromSource(gl, GL_FRAGMENT_SHADER, kFragmentShader);
|
| + if (!fragment_shader)
|
| + return false;
|
| + gl->AttachShader(program_, fragment_shader);
|
| + gl->DeleteShader(fragment_shader);
|
| +
|
| + gl->BindAttribLocation(program_, 0, "in_tex_coord");
|
| + gl->LinkProgram(program_);
|
| + int status;
|
| + gl->GetProgramiv(program_, GL_LINK_STATUS, &status);
|
| + if (!status) {
|
| + int size = 0;
|
| + gl->GetProgramiv(program_, GL_INFO_LOG_LENGTH, &size);
|
| + scoped_array<char> log(new char[size]);
|
| + gl->GetProgramInfoLog(program_, size, NULL, log.get());
|
| + DLOG(ERROR) << "Link failed: " << log.get();
|
| + return false;
|
| + }
|
| + gl->UseProgram(program_);
|
| + int texture_location = gl->GetUniformLocation(program_, "in_texture");
|
| + gl->Uniform1i(texture_location, 0);
|
| +
|
| + gl->GenBuffers(1, &buffer_);
|
| + gl->BindBuffer(GL_ARRAY_BUFFER, buffer_);
|
| + gl->BufferData(GL_ARRAY_BUFFER,
|
| + sizeof(kTexCoords),
|
| + kTexCoords,
|
| + GL_STATIC_DRAW);
|
| + gl->VertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, NULL);
|
| + gl->EnableVertexAttribArray(0);
|
| + return true;
|
| +}
|
| +
|
| +bool RenderWidgetFullscreenPepper::CheckCompositing() {
|
| + bool compositing = webwidget_->isAcceleratedCompositingActive();
|
| + if (compositing != is_accelerated_compositing_active_) {
|
| + didActivateAcceleratedCompositing(compositing);
|
| + }
|
| + return compositing;
|
| +}
|
|
|