Commit ef29f34b authored by backer@chromium.org's avatar backer@chromium.org

Vend common GL context

We can't rely on having a compositor for set-up and tear-down of cross process texture transport. This CL creates a shared offscreen context appropriate for that. It further separates TextureGL objects from CompositorGL objects. In particular
- I've plumbed through the size of the surface backing the Compositor to the Texture
- I've allows the TextureGL to release it's GL resources using the shared context

It's necessary to make the vendor of the offscreen context a LeakySingletonTrait singleton so that we don't race with destruction of GL bindings on process shutdown.

BUG=fixes dereferencing NULL pointers in RWHVVTouch when images come from GPU process
TEST=3D CSS on TOUCH_UI, views_desktop on Windows

Review URL: http://codereview.chromium.org/7552039

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@98441 0039d316-1c4b-4281-b951-d872f2087c98
parent d6fe4385
......@@ -13,8 +13,8 @@
#include "ui/gfx/gl/gl_bindings.h"
#include "ui/gfx/gl/gl_implementation.h"
#include "ui/gfx/gl/gl_surface_egl.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/gl/gl_surface_glx.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/transform.h"
namespace {
......@@ -22,8 +22,7 @@ namespace {
class AcceleratedSurfaceContainerTouchEGL
: public AcceleratedSurfaceContainerTouch {
public:
AcceleratedSurfaceContainerTouchEGL(ui::CompositorGL* compositor,
const gfx::Size& size,
AcceleratedSurfaceContainerTouchEGL(const gfx::Size& size,
uint64 surface_handle);
// TextureGL implementation
virtual void Draw(const ui::TextureDrawParams& params,
......@@ -33,14 +32,14 @@ class AcceleratedSurfaceContainerTouchEGL
~AcceleratedSurfaceContainerTouchEGL();
void* image_;
DISALLOW_COPY_AND_ASSIGN(AcceleratedSurfaceContainerTouchEGL);
};
class AcceleratedSurfaceContainerTouchGLX
: public AcceleratedSurfaceContainerTouch {
public:
AcceleratedSurfaceContainerTouchGLX(ui::CompositorGL* compositor,
const gfx::Size& size,
AcceleratedSurfaceContainerTouchGLX(const gfx::Size& size,
uint64 surface_handle);
// TextureGL implementation
virtual void Draw(const ui::TextureDrawParams& params,
......@@ -51,6 +50,7 @@ class AcceleratedSurfaceContainerTouchGLX
XID pixmap_;
XID glx_pixmap_;
DISALLOW_COPY_AND_ASSIGN(AcceleratedSurfaceContainerTouchGLX);
};
......@@ -62,12 +62,13 @@ class ScopedPtrXFree {
};
AcceleratedSurfaceContainerTouchEGL::AcceleratedSurfaceContainerTouchEGL(
ui::CompositorGL* compositor,
const gfx::Size& size,
uint64 surface_handle)
: AcceleratedSurfaceContainerTouch(compositor, size),
: AcceleratedSurfaceContainerTouch(size),
image_(NULL) {
compositor_->MakeCurrent();
ui::SharedResources* instance = ui::SharedResources::GetInstance();
DCHECK(instance);
instance->MakeSharedContextCurrent();
image_ = eglCreateImageKHR(
gfx::GLSurfaceEGL::GetHardwareDisplay(), EGL_NO_CONTEXT,
......@@ -84,6 +85,10 @@ AcceleratedSurfaceContainerTouchEGL::AcceleratedSurfaceContainerTouchEGL(
}
AcceleratedSurfaceContainerTouchEGL::~AcceleratedSurfaceContainerTouchEGL() {
ui::SharedResources* instance = ui::SharedResources::GetInstance();
DCHECK(instance);
instance->MakeSharedContextCurrent();
eglDestroyImageKHR(gfx::GLSurfaceEGL::GetHardwareDisplay(), image_);
glFlush();
}
......@@ -91,7 +96,8 @@ AcceleratedSurfaceContainerTouchEGL::~AcceleratedSurfaceContainerTouchEGL() {
void AcceleratedSurfaceContainerTouchEGL::Draw(
const ui::TextureDrawParams& params,
const gfx::Rect& clip_bounds_in_texture) {
DCHECK(compositor_->program_no_swizzle());
ui::SharedResources* instance = ui::SharedResources::GetInstance();
DCHECK(instance);
ui::TextureDrawParams modified_params = params;
......@@ -103,18 +109,21 @@ void AcceleratedSurfaceContainerTouchEGL::Draw(
modified_params.transform = flipped;
DrawInternal(*compositor_->program_no_swizzle(),
DrawInternal(*instance->program_no_swizzle(),
modified_params,
clip_bounds_in_texture);
}
AcceleratedSurfaceContainerTouchGLX::AcceleratedSurfaceContainerTouchGLX(
ui::CompositorGL* compositor,
const gfx::Size& size,
uint64 surface_handle)
: AcceleratedSurfaceContainerTouch(compositor, size),
: AcceleratedSurfaceContainerTouch(size),
pixmap_(0),
glx_pixmap_(0) {
ui::SharedResources* instance = ui::SharedResources::GetInstance();
DCHECK(instance);
instance->MakeSharedContextCurrent();
// Create pixmap from window.
Display* dpy = gfx::GLSurfaceGLX::GetDisplay();
int event_base, error_base;
......@@ -186,7 +195,6 @@ AcceleratedSurfaceContainerTouchGLX::AcceleratedSurfaceContainerTouchGLX(
dpy, fbconfigs.get()[config], pixmap_, pixmapAttribs);
// Create texture.
compositor_->MakeCurrent();
glGenTextures(1, &texture_id_);
glBindTexture(GL_TEXTURE_2D, texture_id_);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
......@@ -196,6 +204,10 @@ AcceleratedSurfaceContainerTouchGLX::AcceleratedSurfaceContainerTouchGLX(
}
AcceleratedSurfaceContainerTouchGLX::~AcceleratedSurfaceContainerTouchGLX() {
ui::SharedResources* instance = ui::SharedResources::GetInstance();
DCHECK(instance);
instance->MakeSharedContextCurrent();
Display* dpy = gfx::GLSurfaceGLX::GetDisplay();
if (glx_pixmap_)
glXDestroyGLXPixmap(dpy, glx_pixmap_);
......@@ -206,12 +218,14 @@ AcceleratedSurfaceContainerTouchGLX::~AcceleratedSurfaceContainerTouchGLX() {
void AcceleratedSurfaceContainerTouchGLX::Draw(
const ui::TextureDrawParams& params,
const gfx::Rect& clip_bounds_in_texture) {
DCHECK(compositor_->program_no_swizzle());
ui::SharedResources* instance = ui::SharedResources::GetInstance();
DCHECK(instance);
Display* dpy = gfx::GLSurfaceGLX::GetDisplay();
glBindTexture(GL_TEXTURE_2D, texture_id_);
glXBindTexImageEXT(dpy, glx_pixmap_, GLX_FRONT_LEFT_EXT, NULL);
DrawInternal(*compositor_->program_no_swizzle(),
DrawInternal(*instance->program_no_swizzle(),
params,
clip_bounds_in_texture);
glXReleaseTexImageEXT(dpy, glx_pixmap_, GLX_FRONT_LEFT_EXT);
......@@ -220,25 +234,20 @@ void AcceleratedSurfaceContainerTouchGLX::Draw(
} // namespace
AcceleratedSurfaceContainerTouch::AcceleratedSurfaceContainerTouch(
ui::CompositorGL* compositor,
const gfx::Size& size) :
TextureGL(compositor, size) {
const gfx::Size& size) : TextureGL(size) {
}
// static
AcceleratedSurfaceContainerTouch*
AcceleratedSurfaceContainerTouch::CreateAcceleratedSurfaceContainer(
ui::CompositorGL* compositor,
const gfx::Size& size,
uint64 surface_handle) {
switch (gfx::GetGLImplementation()) {
case gfx::kGLImplementationDesktopGL:
return new AcceleratedSurfaceContainerTouchGLX(compositor,
size,
return new AcceleratedSurfaceContainerTouchGLX(size,
surface_handle);
case gfx::kGLImplementationEGLGLES2:
return new AcceleratedSurfaceContainerTouchEGL(compositor,
size,
return new AcceleratedSurfaceContainerTouchEGL(size,
surface_handle);
default:
NOTREACHED();
......
......@@ -16,7 +16,6 @@
class AcceleratedSurfaceContainerTouch : public ui::TextureGL {
public:
static AcceleratedSurfaceContainerTouch* CreateAcceleratedSurfaceContainer(
ui::CompositorGL* compositor,
const gfx::Size& size,
uint64 surface_handle);
......@@ -26,9 +25,7 @@ class AcceleratedSurfaceContainerTouch : public ui::TextureGL {
const gfx::Size& overall_size) OVERRIDE;
protected:
AcceleratedSurfaceContainerTouch(
ui::CompositorGL* compositor,
const gfx::Size& size);
explicit AcceleratedSurfaceContainerTouch(const gfx::Size& size);
private:
DISALLOW_COPY_AND_ASSIGN(AcceleratedSurfaceContainerTouch);
......
......@@ -191,7 +191,6 @@ void RenderWidgetHostViewViews::AcceleratedSurfaceSetIOSurface(
int32 width, int32 height, uint64 surface_id) {
accelerated_surface_containers_[surface_id] =
AcceleratedSurfaceContainerTouch::CreateAcceleratedSurfaceContainer(
static_cast<ui::CompositorGL*>(GetWidget()->GetCompositor()),
gfx::Size(width, height),
surface_id);
}
......
......@@ -10,18 +10,18 @@
#include "ui/gfx/compositor/compositor_export.h"
#include "ui/gfx/transform.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/gfx/size.h"
class SkCanvas;
namespace gfx {
class Point;
class Rect;
class Size;
}
namespace ui {
struct TextureDrawParams {
TextureDrawParams() : transform(), blend(false) {}
TextureDrawParams() : transform(), blend(false), compositor_size() {}
// The transform to be applied to the texture.
ui::Transform transform;
......@@ -30,6 +30,9 @@ struct TextureDrawParams {
// Otherwise, the drawn pixels clobber the old pixels.
bool blend;
// The size of the surface that the texture is drawn to.
gfx::Size compositor_size;
// Copy and assignment are allowed.
};
......@@ -91,12 +94,23 @@ class COMPOSITOR_EXPORT Compositor : public base::RefCounted<Compositor> {
// Notifies the compositor that the size of the widget that it is
// drawing to has changed.
virtual void OnWidgetSizeChanged(const gfx::Size& size) = 0;
void WidgetSizeChanged(const gfx::Size& size) {
size_ = size;
OnWidgetSizeChanged();
}
// Returns the size of the widget that is being drawn to.
const gfx::Size& size() { return size_; }
protected:
explicit Compositor(const gfx::Size& size) : size_(size) {}
virtual ~Compositor() {}
virtual void OnWidgetSizeChanged() = 0;
private:
gfx::Size size_;
friend class base::RefCounted<Compositor>;
};
......
This diff is collapsed.
......@@ -8,6 +8,8 @@
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/singleton.h"
#include "base/memory/ref_counted.h"
#include "ui/gfx/compositor/compositor.h"
#include "ui/gfx/size.h"
......@@ -22,9 +24,48 @@ namespace ui {
class CompositorGL;
class TextureProgramGL;
// We share resources (such as shaders) between different Compositors via
// GLContext sharing so that we only have to create/destroy them once.
class COMPOSITOR_EXPORT SharedResources {
public:
static SharedResources* GetInstance();
bool MakeSharedContextCurrent();
// Creates a context that shares the resources hosted by this singleton.
scoped_refptr<gfx::GLContext> CreateContext(gfx::GLSurface* surface);
ui::TextureProgramGL* program_no_swizzle() {
return program_no_swizzle_.get();
}
ui::TextureProgramGL* program_swizzle() {
return program_swizzle_.get();
}
private:
friend struct DefaultSingletonTraits<SharedResources>;
SharedResources();
virtual ~SharedResources();
bool Initialize();
void Destroy();
bool initialized_;
scoped_refptr<gfx::GLContext> context_;
scoped_refptr<gfx::GLSurface> surface_;
scoped_ptr<ui::TextureProgramGL> program_swizzle_;
scoped_ptr<ui::TextureProgramGL> program_no_swizzle_;
DISALLOW_COPY_AND_ASSIGN(SharedResources);
};
class COMPOSITOR_EXPORT TextureGL : public Texture {
public:
explicit TextureGL(CompositorGL* compositor);
TextureGL();
virtual void SetCanvas(const SkCanvas& canvas,
const gfx::Point& origin,
......@@ -39,7 +80,7 @@ class COMPOSITOR_EXPORT TextureGL : public Texture {
const gfx::Rect& clip_bounds_in_texture) OVERRIDE;
protected:
TextureGL(CompositorGL* compositor, const gfx::Size& size);
explicit TextureGL(const gfx::Size& size);
virtual ~TextureGL();
// Actually draws the texture.
......@@ -50,7 +91,6 @@ class COMPOSITOR_EXPORT TextureGL : public Texture {
unsigned int texture_id_;
gfx::Size size_;
CompositorGL* compositor_;
private:
DISALLOW_COPY_AND_ASSIGN(TextureGL);
......@@ -64,8 +104,8 @@ class COMPOSITOR_EXPORT CompositorGL : public Compositor {
void MakeCurrent();
gfx::Size GetSize();
TextureProgramGL* program_no_swizzle();
TextureProgramGL* program_swizzle();
protected:
virtual void OnWidgetSizeChanged() OVERRIDE;
private:
// Overridden from Compositor.
......@@ -74,14 +114,11 @@ class COMPOSITOR_EXPORT CompositorGL : public Compositor {
virtual void NotifyEnd() OVERRIDE;
virtual void Blur(const gfx::Rect& bounds) OVERRIDE;
virtual void SchedulePaint() OVERRIDE;
virtual void OnWidgetSizeChanged(const gfx::Size& size) OVERRIDE;
// The GL context used for compositing.
scoped_refptr<gfx::GLSurface> gl_surface_;
scoped_refptr<gfx::GLContext> gl_context_;
gfx::Size size_;
// Keep track of whether compositing has started or not.
bool started_;
......
This diff is collapsed.
......@@ -92,6 +92,7 @@ void Layer::Draw() {
// Only blend for transparent child layers.
// The root layer will clobber the cleared bg.
texture_draw_params.blend = parent_ != NULL && !fills_bounds_opaquely_;
texture_draw_params.compositor_size = compositor_->size();
#if defined(OS_WIN)
texture_->Draw(texture_draw_params);
......
......@@ -2358,7 +2358,9 @@ class TestCompositor : public ui::Compositor {
virtual void NotifyEnd() OVERRIDE {}
virtual void Blur(const gfx::Rect& bounds) OVERRIDE {}
virtual void SchedulePaint() OVERRIDE {}
virtual void OnWidgetSizeChanged(const gfx::Size& size) OVERRIDE {}
protected:
virtual void OnWidgetSizeChanged() OVERRIDE {}
private:
DISALLOW_COPY_AND_ASSIGN(TestCompositor);
......
......@@ -1350,7 +1350,7 @@ void NativeWidgetGtk::OnSizeAllocate(GtkWidget* widget,
return;
size_ = new_size;
if (compositor_.get())
compositor_->OnWidgetSizeChanged(size_);
compositor_->WidgetSizeChanged(size_);
delegate_->OnNativeWidgetSizeChanged(size_);
if (GetWidget()->non_client_view()) {
......
......@@ -2304,7 +2304,7 @@ void NativeWidgetWin::ClientAreaSizeChanged() {
gfx::Size s(std::max(0, static_cast<int>(r.right - r.left)),
std::max(0, static_cast<int>(r.bottom - r.top)));
if (compositor_.get())
compositor_->OnWidgetSizeChanged(s);
compositor_->WidgetSizeChanged(s);
delegate_->OnNativeWidgetSizeChanged(s);
if (use_layered_buffer_) {
layered_window_contents_.reset(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment