| Index: ui/gl/gl_surface_ozone.cc
|
| diff --git a/ui/gl/gl_surface_ozone.cc b/ui/gl/gl_surface_ozone.cc
|
| index cba706bda4e030b6daa599525846ebebbc847640..0ddc1a413b03af6e0cebac38ba8990ce98c83ac6 100644
|
| --- a/ui/gl/gl_surface_ozone.cc
|
| +++ b/ui/gl/gl_surface_ozone.cc
|
| @@ -14,6 +14,8 @@
|
| #include "ui/gl/gl_surface_osmesa.h"
|
| #include "ui/gl/gl_surface_stub.h"
|
| #include "ui/gl/scoped_make_current.h"
|
| +#include "ui/ozone/gpu/gpu_memory_buffer_factory_ozone_native_buffer.h"
|
| +#include "ui/ozone/public/native_pixmap.h"
|
| #include "ui/ozone/public/surface_factory_ozone.h"
|
| #include "ui/ozone/public/surface_ozone_egl.h"
|
|
|
| @@ -157,7 +159,7 @@ class GL_EXPORT GLSurfaceOzoneSurfaceless : public SurfacelessEGL {
|
| return SwapBuffersAsync(callback);
|
| }
|
|
|
| - private:
|
| + protected:
|
| ~GLSurfaceOzoneSurfaceless() override {
|
| Destroy(); // EGL surface must be destroyed before SurfaceOzone
|
| }
|
| @@ -194,6 +196,93 @@ class GL_EXPORT GLSurfaceOzoneSurfaceless : public SurfacelessEGL {
|
| DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneSurfaceless);
|
| };
|
|
|
| +// This provides surface-like semantics implemented through surfaceless.
|
| +// A framebuffer is bound automatically and re-bound at each swap.
|
| +class GL_EXPORT GLSurfaceOzoneSurfacelessSurfaceImpl
|
| + : public GLSurfaceOzoneSurfaceless {
|
| + public:
|
| + GLSurfaceOzoneSurfacelessSurfaceImpl(
|
| + scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface,
|
| + AcceleratedWidget widget)
|
| + : GLSurfaceOzoneSurfaceless(ozone_surface.Pass(), widget),
|
| + fbo_(0),
|
| + current_surface_(0) {
|
| + textures_[0] = 0;
|
| + textures_[1] = 0;
|
| + }
|
| +
|
| + unsigned int GetBackingFrameBufferObject() override { return fbo_; }
|
| +
|
| + bool OnMakeCurrent(GLContext* context) override {
|
| + if (!fbo_) {
|
| + glGenFramebuffersEXT(1, &fbo_);
|
| + if (!fbo_)
|
| + return false;
|
| + glGenTextures(2, textures_);
|
| + // Create and bind our pixmaps.
|
| + ResizePixmaps();
|
| + }
|
| + BindFramebuffer();
|
| + return SurfacelessEGL::OnMakeCurrent(context);
|
| + }
|
| +
|
| + bool Resize(const gfx::Size& size) override {
|
| + return GLSurfaceOzoneSurfaceless::Resize(size) && ResizePixmaps();
|
| + }
|
| +
|
| + bool SupportsPostSubBuffer() override { return false; }
|
| +
|
| + bool SwapBuffers() override {
|
| + bool ret = images_[current_surface_]->ScheduleOverlayPlane(
|
| + widget_, 0, OverlayTransform::OVERLAY_TRANSFORM_NONE,
|
| + gfx::Rect(GetSize()), gfx::RectF(1, 1)) &&
|
| + GLSurfaceOzoneSurfaceless::SwapBuffers();
|
| + current_surface_ ^= 1;
|
| + BindFramebuffer();
|
| + return ret;
|
| + }
|
| +
|
| + private:
|
| + ~GLSurfaceOzoneSurfacelessSurfaceImpl() override {
|
| + glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
| + glDeleteTextures(2, textures_);
|
| + glDeleteFramebuffers(1, &fbo_);
|
| + }
|
| +
|
| + void BindFramebuffer() {
|
| + glBindFramebufferEXT(GL_FRAMEBUFFER, fbo_);
|
| + glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
| + GL_TEXTURE_2D, textures_[current_surface_], 0);
|
| + }
|
| +
|
| + bool ResizePixmaps() {
|
| + if (!fbo_)
|
| + return true;
|
| + for (int i = 0; i < 2; i++) {
|
| + scoped_refptr<ui::NativePixmap> pixmap =
|
| + ui::SurfaceFactoryOzone::GetInstance()->CreateNativePixmap(
|
| + widget_, GetSize(), ui::SurfaceFactoryOzone::RGBA_8888,
|
| + ui::SurfaceFactoryOzone::SCANOUT);
|
| + if (!pixmap)
|
| + return false;
|
| + images_[i] =
|
| + ui::GpuMemoryBufferFactoryOzoneNativeBuffer::CreateImageForPixmap(
|
| + pixmap, GetSize(), GpuMemoryBuffer::Format::RGBA_8888, GL_RGBA);
|
| + // Bind image to texture
|
| + glBindTexture(GL_TEXTURE_EXTERNAL_OES, textures_[i]);
|
| + if (!images_[i]->BindTexImage(GL_TEXTURE_EXTERNAL_OES))
|
| + return false;
|
| + }
|
| + return true;
|
| + }
|
| +
|
| + GLuint fbo_;
|
| + GLuint textures_[2];
|
| + scoped_refptr<GLImage> images_[2];
|
| + int current_surface_;
|
| + DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneSurfacelessSurfaceImpl);
|
| +};
|
| +
|
| } // namespace
|
|
|
| // static
|
| @@ -215,6 +304,27 @@ bool GLSurface::InitializeOneOffInternal() {
|
| }
|
|
|
| // static
|
| +scoped_refptr<GLSurface> GLSurface::CreateSurfacelessViewGLSurface(
|
| + gfx::AcceleratedWidget window) {
|
| + if (GetGLImplementation() == kGLImplementationEGLGLES2 &&
|
| + window != kNullAcceleratedWidget &&
|
| + GLSurfaceEGL::IsEGLSurfacelessContextSupported() &&
|
| + ui::SurfaceFactoryOzone::GetInstance()->CanShowPrimaryPlaneAsOverlay()) {
|
| + scoped_ptr<ui::SurfaceOzoneEGL> surface_ozone =
|
| + ui::SurfaceFactoryOzone::GetInstance()
|
| + ->CreateSurfacelessEGLSurfaceForWidget(window);
|
| + if (!surface_ozone)
|
| + return NULL;
|
| + scoped_refptr<GLSurface> surface;
|
| + surface = new GLSurfaceOzoneSurfaceless(surface_ozone.Pass(), window);
|
| + if (surface->Initialize())
|
| + return surface;
|
| + }
|
| +
|
| + return nullptr;
|
| +}
|
| +
|
| +// static
|
| scoped_refptr<GLSurface> GLSurface::CreateViewGLSurface(
|
| gfx::AcceleratedWidget window) {
|
| if (GetGLImplementation() == kGLImplementationOSMesaGL) {
|
| @@ -234,7 +344,8 @@ scoped_refptr<GLSurface> GLSurface::CreateViewGLSurface(
|
| ->CreateSurfacelessEGLSurfaceForWidget(window);
|
| if (!surface_ozone)
|
| return NULL;
|
| - surface = new GLSurfaceOzoneSurfaceless(surface_ozone.Pass(), window);
|
| + surface = new GLSurfaceOzoneSurfacelessSurfaceImpl(surface_ozone.Pass(),
|
| + window);
|
| } else {
|
| scoped_ptr<ui::SurfaceOzoneEGL> surface_ozone =
|
| ui::SurfaceFactoryOzone::GetInstance()->CreateEGLSurfaceForWidget(
|
|
|