summaryrefslogtreecommitdiffstats
path: root/ui/gl
diff options
context:
space:
mode:
authorepenner@chromium.org <epenner@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-04-18 00:25:04 +0000
committerepenner@chromium.org <epenner@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-04-18 00:25:04 +0000
commitcafa295eb0c24cd3d8b5518bfe3d83544552888a (patch)
treea38ce1c2f6e6ea04335d37211571b200723bae9d /ui/gl
parent1270ea67ad7abc29d7ac452b41e14cb1656b7f5d (diff)
downloadchromium_src-cafa295eb0c24cd3d8b5518bfe3d83544552888a.zip
chromium_src-cafa295eb0c24cd3d8b5518bfe3d83544552888a.tar.gz
chromium_src-cafa295eb0c24cd3d8b5518bfe3d83544552888a.tar.bz2
gpu: Fix Vivante's "hisilicon" GPUs
This fixes "Hisilicon" GPUs, which is an instance of a Vivante's GPU design. This involves enabling virtual contexts, since they don't support share-groups, and further adds a work-around for switching surfaces. Without the work- around the view surface "inherits" the size of the last bound surface (which for Chrome tends to be a 1x1 pbuffer) resulting in a black screen. The following steps "repair" the view surface every time it is made current: - Make it current. - Bind the default frame-buffer. - Make it not current. - Destroy/recreate it from the native handle. - Make it current again. NOTE: The "Recreate" function is added to surface because the Destroy/Initialize may be intercepted or modified by wrapper surface classes. Recreate is similar to resize, which after being forwarded by a wrapper can call Destroy/Initialize on the 'real' surface. BUG=179250, 229643 NOTRY=true No try, since it's Android only and already tested. Review URL: https://chromiumcodereview.appspot.com/13140006 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@194737 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/gl')
-rw-r--r--ui/gl/gl_context_egl.cc36
-rw-r--r--ui/gl/gl_context_egl.h2
-rw-r--r--ui/gl/gl_surface.cc24
-rw-r--r--ui/gl/gl_surface.h11
-rw-r--r--ui/gl/gl_surface_egl.cc22
-rw-r--r--ui/gl/gl_surface_egl.h4
6 files changed, 94 insertions, 5 deletions
diff --git a/ui/gl/gl_context_egl.cc b/ui/gl/gl_context_egl.cc
index 52c60e2..c29eb2a 100644
--- a/ui/gl/gl_context_egl.cc
+++ b/ui/gl/gl_context_egl.cc
@@ -112,6 +112,9 @@ bool GLContextEGL::MakeCurrent(GLSurface* surface) {
return false;
}
+ if (!RecreateSurfaceIfNeeded(surface))
+ return false;
+
if (!surface->OnMakeCurrent(this)) {
LOG(ERROR) << "Could not make current.";
return false;
@@ -121,6 +124,39 @@ bool GLContextEGL::MakeCurrent(GLSurface* surface) {
return true;
}
+bool GLContextEGL::RecreateSurfaceIfNeeded(GLSurface* surface) {
+ if (!surface || !surface->RecreateOnMakeCurrent())
+ return true;
+
+ // This is specifically needed for Vivante GPU's on Android.
+ // A native view surface will not be configured correctly
+ // unless we do all of the following steps after making the
+ // surface current.
+ GLint fbo = 0;
+ glGetIntegerv(GL_FRAMEBUFFER_BINDING, &fbo);
+ glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
+
+ eglMakeCurrent(display_,
+ EGL_NO_SURFACE,
+ EGL_NO_SURFACE,
+ EGL_NO_CONTEXT);
+ if (!surface->Recreate()) {
+ LOG(ERROR) << "Failed to recreate surface";
+ return false;
+ }
+ if (!eglMakeCurrent(display_,
+ surface->GetHandle(),
+ surface->GetHandle(),
+ context_)) {
+ LOG(ERROR) << "eglMakeCurrent failed with error "
+ << GetLastEGLErrorString();
+ return false;
+ }
+
+ glBindFramebufferEXT(GL_FRAMEBUFFER, fbo);
+ return true;
+}
+
void GLContextEGL::ReleaseCurrent(GLSurface* surface) {
if (!IsCurrent(surface))
return;
diff --git a/ui/gl/gl_context_egl.h b/ui/gl/gl_context_egl.h
index e45cc25..ea61976 100644
--- a/ui/gl/gl_context_egl.h
+++ b/ui/gl/gl_context_egl.h
@@ -36,6 +36,8 @@ class GLContextEGL : public GLContext {
virtual bool WasAllocatedUsingRobustnessExtension() OVERRIDE;
virtual bool GetTotalGpuMemory(size_t* bytes) OVERRIDE;
+ bool RecreateSurfaceIfNeeded(GLSurface* surface);
+
protected:
virtual ~GLContextEGL();
diff --git a/ui/gl/gl_surface.cc b/ui/gl/gl_surface.cc
index 0feeb34..fc271a2 100644
--- a/ui/gl/gl_surface.cc
+++ b/ui/gl/gl_surface.cc
@@ -84,6 +84,11 @@ bool GLSurface::Resize(const gfx::Size& size) {
return false;
}
+bool GLSurface::Recreate() {
+ NOTIMPLEMENTED();
+ return false;
+}
+
bool GLSurface::DeferDraws() {
return false;
}
@@ -145,6 +150,13 @@ VSyncProvider* GLSurface::GetVSyncProvider() {
return NULL;
}
+bool GLSurface::RecreateOnMakeCurrent() {
+ return false;
+}
+
+void GLSurface::SetRecreateOnMakeCurrent(bool recreate) {
+}
+
GLSurface* GLSurface::GetCurrent() {
return current_surface_.Pointer()->Get();
}
@@ -185,6 +197,10 @@ bool GLSurfaceAdapter::Resize(const gfx::Size& size) {
return surface_->Resize(size);
}
+bool GLSurfaceAdapter::Recreate() {
+ return surface_->Recreate();
+}
+
bool GLSurfaceAdapter::DeferDraws() {
return surface_->DeferDraws();
}
@@ -249,6 +265,14 @@ VSyncProvider* GLSurfaceAdapter::GetVSyncProvider() {
return surface_->GetVSyncProvider();
}
+bool GLSurfaceAdapter::RecreateOnMakeCurrent() {
+ return surface_->RecreateOnMakeCurrent();
+}
+
+void GLSurfaceAdapter::SetRecreateOnMakeCurrent(bool recreate) {
+ surface_->SetRecreateOnMakeCurrent(recreate);
+}
+
GLSurfaceAdapter::~GLSurfaceAdapter() {}
} // namespace gfx
diff --git a/ui/gl/gl_surface.h b/ui/gl/gl_surface.h
index 6924685..ac2be89 100644
--- a/ui/gl/gl_surface.h
+++ b/ui/gl/gl_surface.h
@@ -39,6 +39,9 @@ class GL_EXPORT GLSurface : public base::RefCounted<GLSurface> {
virtual bool Resize(const gfx::Size& size);
+ // Recreate the surface without changing the size.
+ virtual bool Recreate();
+
// Unschedule the GpuScheduler and return true to abort the processing of
// a GL draw call to this surface and defer it until the GpuScheduler is
// rescheduled.
@@ -102,6 +105,11 @@ class GL_EXPORT GLSurface : public base::RefCounted<GLSurface> {
// of screen refresh. If unavailable, returns NULL.
virtual VSyncProvider* GetVSyncProvider();
+ // Certain surfaces need to be destroyed and recreated
+ // every time they are made the current surface.
+ virtual bool RecreateOnMakeCurrent();
+ virtual void SetRecreateOnMakeCurrent(bool recreate);
+
// Create a GL surface that renders directly to a view.
static scoped_refptr<GLSurface> CreateViewGLSurface(
bool software,
@@ -137,6 +145,7 @@ class GL_EXPORT GLSurfaceAdapter : public GLSurface {
virtual bool Initialize() OVERRIDE;
virtual void Destroy() OVERRIDE;
virtual bool Resize(const gfx::Size& size) OVERRIDE;
+ virtual bool Recreate() OVERRIDE;
virtual bool DeferDraws() OVERRIDE;
virtual bool IsOffscreen() OVERRIDE;
virtual bool SwapBuffers() OVERRIDE;
@@ -153,6 +162,8 @@ class GL_EXPORT GLSurfaceAdapter : public GLSurface {
virtual void* GetConfig() OVERRIDE;
virtual unsigned GetFormat() OVERRIDE;
virtual VSyncProvider* GetVSyncProvider() OVERRIDE;
+ virtual bool RecreateOnMakeCurrent() OVERRIDE;
+ virtual void SetRecreateOnMakeCurrent(bool recreate) OVERRIDE;
GLSurface* surface() const { return surface_.get(); }
diff --git a/ui/gl/gl_surface_egl.cc b/ui/gl/gl_surface_egl.cc
index 3b81daf..b57655651 100644
--- a/ui/gl/gl_surface_egl.cc
+++ b/ui/gl/gl_surface_egl.cc
@@ -399,18 +399,30 @@ bool NativeViewGLSurfaceEGL::Resize(const gfx::Size& size) {
if (was_current)
current_context->ReleaseCurrent(this);
- Destroy();
+ Recreate();
+
+ if (was_current)
+ return current_context->MakeCurrent(this);
+ return true;
+}
+bool NativeViewGLSurfaceEGL::Recreate() {
+ Destroy();
if (!Initialize()) {
- LOG(ERROR) << "Failed to resize pbuffer.";
+ LOG(ERROR) << "Failed to create surface.";
return false;
}
-
- if (was_current)
- return current_context->MakeCurrent(this);
return true;
}
+bool NativeViewGLSurfaceEGL::RecreateOnMakeCurrent() {
+ return recreate_on_make_current_;
+}
+
+void NativeViewGLSurfaceEGL::SetRecreateOnMakeCurrent(bool recreate) {
+ recreate_on_make_current_ = recreate;
+}
+
EGLSurface NativeViewGLSurfaceEGL::GetHandle() {
return surface_;
}
diff --git a/ui/gl/gl_surface_egl.h b/ui/gl/gl_surface_egl.h
index 17e6e94..c54fbc0 100644
--- a/ui/gl/gl_surface_egl.h
+++ b/ui/gl/gl_surface_egl.h
@@ -60,6 +60,7 @@ class GL_EXPORT NativeViewGLSurfaceEGL : public GLSurfaceEGL {
virtual bool Initialize() OVERRIDE;
virtual void Destroy() OVERRIDE;
virtual bool Resize(const gfx::Size& size) OVERRIDE;
+ virtual bool Recreate() OVERRIDE;
virtual bool IsOffscreen() OVERRIDE;
virtual bool SwapBuffers() OVERRIDE;
virtual gfx::Size GetSize() OVERRIDE;
@@ -67,6 +68,8 @@ class GL_EXPORT NativeViewGLSurfaceEGL : public GLSurfaceEGL {
virtual std::string GetExtensions() OVERRIDE;
virtual bool PostSubBuffer(int x, int y, int width, int height) OVERRIDE;
virtual VSyncProvider* GetVSyncProvider() OVERRIDE;
+ virtual bool RecreateOnMakeCurrent() OVERRIDE;
+ virtual void SetRecreateOnMakeCurrent(bool recreate) OVERRIDE;
protected:
virtual ~NativeViewGLSurfaceEGL();
@@ -77,6 +80,7 @@ class GL_EXPORT NativeViewGLSurfaceEGL : public GLSurfaceEGL {
EGLSurface surface_;
bool supports_post_sub_buffer_;
EGLConfig config_;
+ bool recreate_on_make_current_;
scoped_ptr<VSyncProvider> vsync_provider_;