summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbacker@chromium.org <backer@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-26 17:28:45 +0000
committerbacker@chromium.org <backer@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-26 17:28:45 +0000
commitef29f34b4144247658d1580049eb968b0394eccb (patch)
tree80b8b91f4c86cda87510fb6eacfcf22bd61d5b37
parentd6fe4385d153e0a57f693117ad4db2481bdbbea6 (diff)
downloadchromium_src-ef29f34b4144247658d1580049eb968b0394eccb.zip
chromium_src-ef29f34b4144247658d1580049eb968b0394eccb.tar.gz
chromium_src-ef29f34b4144247658d1580049eb968b0394eccb.tar.bz2
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
-rw-r--r--chrome/browser/renderer_host/accelerated_surface_container_touch.cc55
-rw-r--r--chrome/browser/renderer_host/accelerated_surface_container_touch.h5
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_views_touch.cc1
-rw-r--r--ui/gfx/compositor/compositor.h20
-rw-r--r--ui/gfx/compositor/compositor_gl.cc258
-rw-r--r--ui/gfx/compositor/compositor_gl.h53
-rw-r--r--ui/gfx/compositor/compositor_win.cc181
-rw-r--r--ui/gfx/compositor/layer.cc1
-rw-r--r--views/view_unittest.cc4
-rw-r--r--views/widget/native_widget_gtk.cc2
-rw-r--r--views/widget/native_widget_win.cc2
11 files changed, 312 insertions, 270 deletions
diff --git a/chrome/browser/renderer_host/accelerated_surface_container_touch.cc b/chrome/browser/renderer_host/accelerated_surface_container_touch.cc
index e3a5237..ab0db73 100644
--- a/chrome/browser/renderer_host/accelerated_surface_container_touch.cc
+++ b/chrome/browser/renderer_host/accelerated_surface_container_touch.cc
@@ -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();
diff --git a/chrome/browser/renderer_host/accelerated_surface_container_touch.h b/chrome/browser/renderer_host/accelerated_surface_container_touch.h
index e38532a..4303cd8 100644
--- a/chrome/browser/renderer_host/accelerated_surface_container_touch.h
+++ b/chrome/browser/renderer_host/accelerated_surface_container_touch.h
@@ -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);
diff --git a/chrome/browser/renderer_host/render_widget_host_view_views_touch.cc b/chrome/browser/renderer_host/render_widget_host_view_views_touch.cc
index 2357f4d..2cc3a6c 100644
--- a/chrome/browser/renderer_host/render_widget_host_view_views_touch.cc
+++ b/chrome/browser/renderer_host/render_widget_host_view_views_touch.cc
@@ -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);
}
diff --git a/ui/gfx/compositor/compositor.h b/ui/gfx/compositor/compositor.h
index df575dd..42bb770 100644
--- a/ui/gfx/compositor/compositor.h
+++ b/ui/gfx/compositor/compositor.h
@@ -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>;
};
diff --git a/ui/gfx/compositor/compositor_gl.cc b/ui/gfx/compositor/compositor_gl.cc
index 6d7bd29..c9e6dfa 100644
--- a/ui/gfx/compositor/compositor_gl.cc
+++ b/ui/gfx/compositor/compositor_gl.cc
@@ -84,35 +84,6 @@ class TextureProgramSwizzleGL : public ui::TextureProgramGL {
DISALLOW_COPY_AND_ASSIGN(TextureProgramSwizzleGL);
};
-// We share between compositor contexts so that we don't have to compile
-// shaders if they have already been compiled in another context.
-class SharedResources {
- public:
- static SharedResources* GetInstance();
-
- // Creates a context with shaders active.
- scoped_refptr<gfx::GLContext> CreateContext(gfx::GLSurface* surface);
- void ContextDestroyed();
-
- 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();
-
- scoped_refptr<gfx::GLShareGroup> share_group_;
- scoped_ptr<ui::TextureProgramGL> program_swizzle_;
- scoped_ptr<ui::TextureProgramGL> program_no_swizzle_;
-
- DISALLOW_COPY_AND_ASSIGN(SharedResources);
-};
-
GLuint CompileShader(GLenum type, const GLchar* source) {
GLuint shader = glCreateShader(type);
if (!shader)
@@ -175,61 +146,6 @@ bool TextureProgramSwizzleGL::Initialize() {
return InitializeCommon();
}
-SharedResources::SharedResources() {
-}
-
-SharedResources::~SharedResources() {
-}
-
-// static
-SharedResources* SharedResources::GetInstance() {
- return Singleton<SharedResources>::get();
-}
-
-scoped_refptr<gfx::GLContext> SharedResources::CreateContext(
- gfx::GLSurface* surface) {
- if (share_group_.get()) {
- return gfx::GLContext::CreateGLContext(share_group_.get(), surface);
- } else {
- scoped_refptr<gfx::GLContext> context(
- gfx::GLContext::CreateGLContext(NULL, surface));
- context->MakeCurrent(surface);
-
- if (!program_no_swizzle_.get()) {
- scoped_ptr<ui::TextureProgramGL> temp_program(
- new TextureProgramNoSwizzleGL());
- if (!temp_program->Initialize()) {
- LOG(ERROR) << "Unable to initialize shaders (context = "
- << static_cast<void*>(context.get()) << ")";
- return NULL;
- }
- program_no_swizzle_.swap(temp_program);
- }
-
- if (!program_swizzle_.get()) {
- scoped_ptr<ui::TextureProgramGL> temp_program(
- new TextureProgramSwizzleGL());
- if (!temp_program->Initialize()) {
- LOG(ERROR) << "Unable to initialize shaders (context = "
- << static_cast<void*>(context.get()) << ")";
- return NULL;
- }
- program_swizzle_.swap(temp_program);
- }
-
- share_group_ = context->share_group();
- return context;
- }
-}
-
-void SharedResources::ContextDestroyed() {
- if (share_group_.get() && share_group_->GetHandle() == NULL) {
- share_group_ = NULL;
- program_no_swizzle_.reset();
- program_swizzle_.reset();
- }
-}
-
} // namespace
namespace ui {
@@ -275,20 +191,117 @@ bool TextureProgramGL::InitializeCommon() {
return true;
}
-TextureGL::TextureGL(CompositorGL* compositor) : texture_id_(0),
- compositor_(compositor) {
+SharedResources::SharedResources() : initialized_(false) {
+}
+
+
+SharedResources::~SharedResources() {
+}
+
+// static
+SharedResources* SharedResources::GetInstance() {
+ // We use LeakySingletonTraits so that we don't race with
+ // the tear down of the gl_bindings.
+ SharedResources* instance = Singleton<SharedResources,
+ LeakySingletonTraits<SharedResources> >::get();
+ if (instance->Initialize()) {
+ return instance;
+ } else {
+ instance->Destroy();
+ return NULL;
+ }
+}
+
+bool SharedResources::Initialize() {
+ if (initialized_)
+ return true;
+
+ {
+ // The following line of code exists soley to disable IO restrictions
+ // on this thread long enough to perform the GL bindings.
+ // TODO(wjmaclean) Remove this when GL initialisation cleaned up.
+ base::ThreadRestrictions::ScopedAllowIO allow_io;
+ if (!gfx::GLSurface::InitializeOneOff() ||
+ gfx::GetGLImplementation() == gfx::kGLImplementationNone) {
+ LOG(ERROR) << "Could not load the GL bindings";
+ return false;
+ }
+ }
+
+ surface_ = gfx::GLSurface::CreateOffscreenGLSurface(false, gfx::Size(1, 1));
+ if (!surface_.get()) {
+ LOG(ERROR) << "Unable to create offscreen GL surface.";
+ return false;
+ }
+
+ context_ = gfx::GLContext::CreateGLContext(NULL, surface_.get());
+ if (!context_.get()) {
+ LOG(ERROR) << "Unable to create GL context.";
+ return false;
+ }
+
+ program_no_swizzle_.reset();
+ program_swizzle_.reset();
+
+ context_->MakeCurrent(surface_.get());
+
+ scoped_ptr<ui::TextureProgramGL> temp_program_no_swizzle(
+ new TextureProgramNoSwizzleGL());
+ if (!temp_program_no_swizzle->Initialize()) {
+ LOG(ERROR) << "Unable to initialize shader.";
+ return false;
+ }
+
+ scoped_ptr<ui::TextureProgramGL> temp_program_swizzle(
+ new TextureProgramSwizzleGL());
+ if (!temp_program_swizzle->Initialize()) {
+ LOG(ERROR) << "Unable to initialize shader.";
+ return false;
+ }
+
+ program_no_swizzle_.swap(temp_program_no_swizzle);
+ program_swizzle_.swap(temp_program_swizzle);
+
+ initialized_ = true;
+ return true;
+}
+
+void SharedResources::Destroy() {
+ program_swizzle_.reset();
+ program_no_swizzle_.reset();
+
+ context_ = NULL;
+ surface_ = NULL;
+
+ initialized_ = false;
+}
+
+bool SharedResources::MakeSharedContextCurrent() {
+ if (!initialized_)
+ return false;
+ else
+ return context_->MakeCurrent(surface_.get());
+}
+
+scoped_refptr<gfx::GLContext> SharedResources::CreateContext(
+ gfx::GLSurface* surface) {
+ if (initialized_)
+ return gfx::GLContext::CreateGLContext(context_->share_group(), surface);
+ else
+ return NULL;
+}
+
+TextureGL::TextureGL() : texture_id_(0) {
}
-TextureGL::TextureGL(CompositorGL* compositor,
- const gfx::Size& size)
- : texture_id_(0),
- size_(size),
- compositor_(compositor) {
+TextureGL::TextureGL(const gfx::Size& size) : texture_id_(0), size_(size) {
}
TextureGL::~TextureGL() {
if (texture_id_) {
- compositor_->MakeCurrent();
+ SharedResources* instance = SharedResources::GetInstance();
+ DCHECK(instance);
+ instance->MakeSharedContextCurrent();
glDeleteTextures(1, &texture_id_);
}
}
@@ -333,21 +346,27 @@ void TextureGL::SetCanvas(const SkCanvas& canvas,
}
void TextureGL::Draw(const ui::TextureDrawParams& params) {
- DCHECK(compositor_->program_swizzle());
Draw(params, gfx::Rect(0, 0, size_.width(), size_.height()));
}
void TextureGL::Draw(const ui::TextureDrawParams& params,
const gfx::Rect& clip_bounds_in_texture) {
- DCHECK(compositor_->program_swizzle());
- DrawInternal(*compositor_->program_swizzle(), params, clip_bounds_in_texture);
+ SharedResources* instance = SharedResources::GetInstance();
+ DCHECK(instance);
+ DrawInternal(*instance->program_swizzle(),
+ params,
+ clip_bounds_in_texture);
}
+
void TextureGL::DrawInternal(const ui::TextureProgramGL& program,
const ui::TextureDrawParams& params,
const gfx::Rect& clip_bounds_in_texture) {
- // clip clip_bounds_in_layer to size of texture
- gfx::Rect clip_bounds = clip_bounds_in_texture.Intersect(
- gfx::Rect(gfx::Point(0, 0), size_));
+ // Clip clip_bounds_in_texture to size of texture.
+ gfx::Rect clip_bounds = clip_bounds_in_texture.Intersect(
+ gfx::Rect(gfx::Point(0, 0), size_));
+
+ // Verify that compositor_size has been set.
+ DCHECK(params.compositor_size != gfx::Size(0,0));
if (params.blend)
glEnable(GL_BLEND);
@@ -360,8 +379,6 @@ void TextureGL::DrawInternal(const ui::TextureProgramGL& program,
glUniform1i(program.u_tex_loc(), 0);
glBindTexture(GL_TEXTURE_2D, texture_id_);
- gfx::Size window_size = compositor_->GetSize();
-
ui::Transform t;
t.ConcatTranslate(1, 1);
t.ConcatScale(size_.width()/2.0f, size_.height()/2.0f);
@@ -370,15 +387,16 @@ void TextureGL::DrawInternal(const ui::TextureProgramGL& program,
t.ConcatTransform(params.transform); // Add view transform.
- t.ConcatTranslate(0, -window_size.height());
+ t.ConcatTranslate(0, -params.compositor_size.height());
t.ConcatScale(1, -1);
- t.ConcatTranslate(-window_size.width() / 2.0f, -window_size.height() / 2.0f);
- t.ConcatScale(2.0f / window_size.width(), 2.0f / window_size.height());
+ t.ConcatTranslate(-params.compositor_size.width() / 2.0f,
+ -params.compositor_size.height() / 2.0f);
+ t.ConcatScale(2.0f / params.compositor_size.width(),
+ 2.0f / params.compositor_size.height());
GLfloat m[16];
t.matrix().asColMajorf(m);
- // TODO(pkotwicz) window_size != size_, fix this
SkRect texture_rect = SkRect::MakeXYWH(
clip_bounds.x(),
clip_bounds.y(),
@@ -429,7 +447,7 @@ void TextureGL::DrawInternal(const ui::TextureProgramGL& program,
CompositorGL::CompositorGL(gfx::AcceleratedWidget widget,
const gfx::Size& size)
- : size_(size),
+ : Compositor(size),
started_(false) {
gl_surface_ = gfx::GLSurface::CreateViewGLSurface(false, widget);
gl_context_ = SharedResources::GetInstance()->
@@ -441,34 +459,24 @@ CompositorGL::CompositorGL(gfx::AcceleratedWidget widget,
CompositorGL::~CompositorGL() {
gl_context_ = NULL;
- SharedResources::GetInstance()->ContextDestroyed();
}
void CompositorGL::MakeCurrent() {
gl_context_->MakeCurrent(gl_surface_.get());
}
-gfx::Size CompositorGL::GetSize() {
- return size_;
-}
-
-TextureProgramGL* CompositorGL::program_no_swizzle() {
- return SharedResources::GetInstance()->program_no_swizzle();
-}
-
-TextureProgramGL* CompositorGL::program_swizzle() {
- return SharedResources::GetInstance()->program_swizzle();
+void CompositorGL::OnWidgetSizeChanged() {
}
Texture* CompositorGL::CreateTexture() {
- Texture* texture = new TextureGL(this);
+ Texture* texture = new TextureGL();
return texture;
}
void CompositorGL::NotifyStart() {
started_ = true;
gl_context_->MakeCurrent(gl_surface_.get());
- glViewport(0, 0, size_.width(), size_.height());
+ glViewport(0, 0, size().width(), size().height());
glColorMask(true, true, true, true);
#if defined(DEBUG)
@@ -494,21 +502,13 @@ void CompositorGL::SchedulePaint() {
NOTIMPLEMENTED();
}
-void CompositorGL::OnWidgetSizeChanged(const gfx::Size& size) {
- size_ = size;
-}
-
// static
Compositor* Compositor::Create(gfx::AcceleratedWidget widget,
const gfx::Size& size) {
- // The following line of code exists soley to disable IO restrictions
- // on this thread long enough to perform the GL bindings.
- // TODO(wjmaclean) Remove this when GL initialisation cleaned up.
- base::ThreadRestrictions::ScopedAllowIO allow_io;
- if (gfx::GLSurface::InitializeOneOff() &&
- gfx::GetGLImplementation() != gfx::kGLImplementationNone)
+ if (SharedResources::GetInstance() == NULL)
+ return NULL;
+ else
return new CompositorGL(widget, size);
- return NULL;
}
} // namespace ui
diff --git a/ui/gfx/compositor/compositor_gl.h b/ui/gfx/compositor/compositor_gl.h
index 0872d1e..cfa4756 100644
--- a/ui/gfx/compositor/compositor_gl.h
+++ b/ui/gfx/compositor/compositor_gl.h
@@ -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_;
diff --git a/ui/gfx/compositor/compositor_win.cc b/ui/gfx/compositor/compositor_win.cc
index 3afb3c4..346fd13 100644
--- a/ui/gfx/compositor/compositor_win.cc
+++ b/ui/gfx/compositor/compositor_win.cc
@@ -56,7 +56,6 @@ class ViewTexture : public Texture {
const gfx::Point& origin,
const gfx::Size& overall_size) OVERRIDE;
virtual void Draw(const ui::TextureDrawParams& params) OVERRIDE;
-
virtual void Draw(const ui::TextureDrawParams& params,
const gfx::Rect& clip_bounds_in_texture) OVERRIDE;
@@ -97,9 +96,6 @@ class CompositorWin : public Compositor {
void UpdatePerspective(const ui::Transform& transform,
const gfx::Size& view_size);
- // Returns the overall size of the compositor.
- const gfx::Size& GetHostSize();
-
// Returns the index buffer used for drawing a texture.
ID3D10Buffer* GetTextureIndexBuffer();
@@ -109,7 +105,9 @@ class CompositorWin : 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;
+
+ protected:
+ virtual void OnWidgetSizeChanged() OVERRIDE;
private:
enum Direction {
@@ -127,8 +125,6 @@ class CompositorWin : public Compositor {
void InitVertexLayout();
- void Resize(const gfx::Size& size);
-
// Updates the kernel used for blurring. Size is the size of the texture
// being drawn to along the appropriate axis.
void UpdateBlurKernel(Direction direction, int size);
@@ -151,9 +147,6 @@ class CompositorWin : public Compositor {
gfx::AcceleratedWidget host_;
- // Size the device was last created at.
- gfx::Size last_size_;
-
ScopedComPtr<ID3D10Device> device_;
ScopedComPtr<IDXGISwapChain> swap_chain_;
ScopedComPtr<ID3D10RenderTargetView> dest_render_target_view_;
@@ -305,7 +298,7 @@ void ViewTexture::ConvertBitmapToD3DData(
void ViewTexture::CreateVertexBuffer(const gfx::Size& size) {
vertex_buffer_.Release();
- const gfx::Size& host_size = compositor_->GetHostSize();
+ const gfx::Size& host_size = compositor_->size();
float x = static_cast<float>(host_size.width()) / 2.0f;
float y = static_cast<float>(host_size.height()) / 2.0f;
float w = static_cast<float>(size.width());
@@ -332,15 +325,15 @@ void ViewTexture::CreateVertexBuffer(const gfx::Size& size) {
CompositorWin::CompositorWin(gfx::AcceleratedWidget widget,
const gfx::Size& size)
- : host_(widget),
- technique_(NULL),
- last_size_(size) {
+ : Compositor(size),
+ host_(widget),
+ technique_(NULL) {
}
void CompositorWin::Init() {
CreateDevice();
LoadEffects();
- Resize(last_size_);
+ OnWidgetSizeChanged();
InitVertexLayout();
CreateVertexBuffer();
CreateIndexBuffer();
@@ -362,8 +355,8 @@ void CompositorWin::UpdatePerspective(const ui::Transform& transform,
D3DXMATRIX scale_matrix;
D3DXMatrixScaling(
&scale_matrix,
- 2.0f / static_cast<float>(last_size_.width()),
- 2.0f / static_cast<float>(last_size_.height()),
+ 2.0f / static_cast<float>(size().width()),
+ 2.0f / static_cast<float>(size().height()),
1.0f);
// Translate so x and y are from -1,-1 to 1,1.
@@ -387,10 +380,6 @@ void CompositorWin::UpdatePerspective(const ui::Transform& transform,
fx_->GetVariableByName("gWVP")->AsMatrix()->SetMatrix(wvp);
}
-const gfx::Size& CompositorWin::GetHostSize() {
- return last_size_;
-}
-
ID3D10Buffer* CompositorWin::GetTextureIndexBuffer() {
return index_buffer_.get();
}
@@ -469,7 +458,7 @@ void CompositorWin::Blur(const gfx::Rect& bounds) {
D3DXMatrixIdentity(&identity_matrix);
// Horizontal blur from the main texture to blur texture.
- UpdateBlurKernel(HORIZONTAL, last_size_.width());
+ UpdateBlurKernel(HORIZONTAL, size().width());
ID3D10RenderTargetView* target_view = blur_render_target_view_.get();
device_->OMSetRenderTargets(1, &target_view, NULL);
RETURN_IF_FAILED(
@@ -495,7 +484,7 @@ void CompositorWin::Blur(const gfx::Rect& bounds) {
RETURN_IF_FAILED(
blur_fx_->GetVariableByName("textureMap")->AsShaderResource()->
SetResource(blur_texture_shader_view_.get()));
- UpdateBlurKernel(VERTICAL, last_size_.height());
+ UpdateBlurKernel(VERTICAL, size().height());
target_view = main_render_target_view_.get();
device_->OMSetRenderTargets(1, &target_view, NULL);
for(UINT p = 0; p < tech_desc.Passes; ++p)
@@ -518,8 +507,69 @@ void CompositorWin::SchedulePaint() {
InvalidateRect(host_, &bounds, FALSE);
}
-void CompositorWin::OnWidgetSizeChanged(const gfx::Size& size) {
- Resize(size);
+void CompositorWin::OnWidgetSizeChanged() {
+ dest_render_target_view_ = NULL;
+ depth_stencil_buffer_ = NULL;
+ depth_stencil_view_ = NULL;
+
+ main_render_target_view_ = NULL;
+ main_texture_ = NULL;
+ main_texture_shader_view_ = NULL;
+
+ blur_render_target_view_ = NULL;
+ blur_texture_ = NULL;
+ blur_texture_shader_view_ = NULL;
+
+ CreateTexture(size(), main_texture_.Receive(),
+ main_render_target_view_.Receive(),
+ main_texture_shader_view_.Receive());
+
+ CreateTexture(size(), blur_texture_.Receive(),
+ blur_render_target_view_.Receive(),
+ blur_texture_shader_view_.Receive());
+
+ // Resize the swap chain and recreate the render target view.
+ RETURN_IF_FAILED(swap_chain_->ResizeBuffers(
+ 1, size().width(), size().height(), DXGI_FORMAT_R8G8B8A8_UNORM, 0));
+ ScopedComPtr<ID3D10Texture2D> back_buffer;
+ RETURN_IF_FAILED(swap_chain_->GetBuffer(
+ 0, __uuidof(ID3D10Texture2D),
+ reinterpret_cast<void**>(back_buffer.Receive())));
+ RETURN_IF_FAILED(device_->CreateRenderTargetView(
+ back_buffer.get(), 0,
+ dest_render_target_view_.Receive()));
+
+ // Create the depth/stencil buffer and view.
+ D3D10_TEXTURE2D_DESC depth_stencil_desc;
+ depth_stencil_desc.Width = size().width();
+ depth_stencil_desc.Height = size().height();
+ depth_stencil_desc.MipLevels = 1;
+ depth_stencil_desc.ArraySize = 1;
+ depth_stencil_desc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
+ depth_stencil_desc.SampleDesc.Count = 1; // multisampling must match
+ depth_stencil_desc.SampleDesc.Quality = 0; // swap chain values.
+ depth_stencil_desc.Usage = D3D10_USAGE_DEFAULT;
+ depth_stencil_desc.BindFlags = D3D10_BIND_DEPTH_STENCIL;
+ depth_stencil_desc.CPUAccessFlags = 0;
+ depth_stencil_desc.MiscFlags = 0;
+
+ RETURN_IF_FAILED(device_->CreateTexture2D(&depth_stencil_desc, 0,
+ depth_stencil_buffer_.Receive()));
+ RETURN_IF_FAILED(device_->CreateDepthStencilView(
+ depth_stencil_buffer_.get(), 0,
+ depth_stencil_view_.Receive()));
+
+
+ // Set the viewport transform.
+ D3D10_VIEWPORT vp;
+ vp.TopLeftX = 0;
+ vp.TopLeftY = 0;
+ vp.Width = size().width();
+ vp.Height = size().height();
+ vp.MinDepth = 0.0f;
+ vp.MaxDepth = 1.0f;
+
+ device_->RSSetViewports(1, &vp);
}
CompositorWin::~CompositorWin() {
@@ -532,8 +582,8 @@ void CompositorWin::Errored(HRESULT error_code) {
void CompositorWin::CreateDevice() {
DXGI_SWAP_CHAIN_DESC sd;
- sd.BufferDesc.Width = last_size_.width();
- sd.BufferDesc.Height = last_size_.height();
+ sd.BufferDesc.Width = size().width();
+ sd.BufferDesc.Height = size().height();
sd.BufferDesc.RefreshRate.Numerator = 60;
sd.BufferDesc.RefreshRate.Denominator = 1;
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
@@ -616,73 +666,6 @@ void CompositorWin::InitVertexLayout() {
vertex_layout_.Receive()));
}
-void CompositorWin::Resize(const gfx::Size& size) {
- last_size_ = size;
-
- dest_render_target_view_ = NULL;
- depth_stencil_buffer_ = NULL;
- depth_stencil_view_ = NULL;
-
- main_render_target_view_ = NULL;
- main_texture_ = NULL;
- main_texture_shader_view_ = NULL;
-
- blur_render_target_view_ = NULL;
- blur_texture_ = NULL;
- blur_texture_shader_view_ = NULL;
-
- CreateTexture(size, main_texture_.Receive(),
- main_render_target_view_.Receive(),
- main_texture_shader_view_.Receive());
-
- CreateTexture(size, blur_texture_.Receive(),
- blur_render_target_view_.Receive(),
- blur_texture_shader_view_.Receive());
-
- // Resize the swap chain and recreate the render target view.
- RETURN_IF_FAILED(swap_chain_->ResizeBuffers(
- 1, size.width(), size.height(), DXGI_FORMAT_R8G8B8A8_UNORM, 0));
- ScopedComPtr<ID3D10Texture2D> back_buffer;
- RETURN_IF_FAILED(swap_chain_->GetBuffer(
- 0, __uuidof(ID3D10Texture2D),
- reinterpret_cast<void**>(back_buffer.Receive())));
- RETURN_IF_FAILED(device_->CreateRenderTargetView(
- back_buffer.get(), 0,
- dest_render_target_view_.Receive()));
-
- // Create the depth/stencil buffer and view.
- D3D10_TEXTURE2D_DESC depth_stencil_desc;
- depth_stencil_desc.Width = size.width();
- depth_stencil_desc.Height = size.height();
- depth_stencil_desc.MipLevels = 1;
- depth_stencil_desc.ArraySize = 1;
- depth_stencil_desc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
- depth_stencil_desc.SampleDesc.Count = 1; // multisampling must match
- depth_stencil_desc.SampleDesc.Quality = 0; // swap chain values.
- depth_stencil_desc.Usage = D3D10_USAGE_DEFAULT;
- depth_stencil_desc.BindFlags = D3D10_BIND_DEPTH_STENCIL;
- depth_stencil_desc.CPUAccessFlags = 0;
- depth_stencil_desc.MiscFlags = 0;
-
- RETURN_IF_FAILED(device_->CreateTexture2D(&depth_stencil_desc, 0,
- depth_stencil_buffer_.Receive()));
- RETURN_IF_FAILED(device_->CreateDepthStencilView(
- depth_stencil_buffer_.get(), 0,
- depth_stencil_view_.Receive()));
-
-
- // Set the viewport transform.
- D3D10_VIEWPORT vp;
- vp.TopLeftX = 0;
- vp.TopLeftY = 0;
- vp.Width = size.width();
- vp.Height = size.height();
- vp.MinDepth = 0.0f;
- vp.MaxDepth = 1.0f;
-
- device_->RSSetViewports(1, &vp);
-}
-
void CompositorWin::UpdateBlurKernel(Direction direction, int size) {
// Update the blur data.
const int kSize = 13;
@@ -773,14 +756,14 @@ void CompositorWin::CreateIndexBuffer() {
ID3D10Buffer* CompositorWin::CreateVertexBufferForRegion(
const gfx::Rect& bounds) {
float x = static_cast<float>(bounds.x()) /
- static_cast<float>(last_size_.width()) * 2.0f - 1.0f;
+ static_cast<float>(size().width()) * 2.0f - 1.0f;
float max_x =
- x + bounds.width() / static_cast<float>(last_size_.width()) * 2.0f;
+ x + bounds.width() / static_cast<float>(size().width()) * 2.0f;
float y =
- static_cast<float>(last_size_.height() - bounds.y() - bounds.height()) /
- static_cast<float>(last_size_.height()) * 2.0f - 1.0f;
+ static_cast<float>(size().height() - bounds.y() - bounds.height()) /
+ static_cast<float>(size().height()) * 2.0f - 1.0f;
float max_y =
- y + bounds.height() / static_cast<float>(last_size_.height()) * 2.0f;
+ y + bounds.height() / static_cast<float>(size().height()) * 2.0f;
float tex_x = x / 2.0f + .5f;
float max_tex_x = max_x / 2.0f + .5f;
float tex_y = 1.0f - (max_y + 1.0f) / 2.0f;
diff --git a/ui/gfx/compositor/layer.cc b/ui/gfx/compositor/layer.cc
index 214b07e..8061294 100644
--- a/ui/gfx/compositor/layer.cc
+++ b/ui/gfx/compositor/layer.cc
@@ -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);
diff --git a/views/view_unittest.cc b/views/view_unittest.cc
index 09483bc..94d6d4d 100644
--- a/views/view_unittest.cc
+++ b/views/view_unittest.cc
@@ -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);
diff --git a/views/widget/native_widget_gtk.cc b/views/widget/native_widget_gtk.cc
index 75778c9..dae9c95 100644
--- a/views/widget/native_widget_gtk.cc
+++ b/views/widget/native_widget_gtk.cc
@@ -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()) {
diff --git a/views/widget/native_widget_win.cc b/views/widget/native_widget_win.cc
index 8c20b03..9e1415b 100644
--- a/views/widget/native_widget_win.cc
+++ b/views/widget/native_widget_win.cc
@@ -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(