summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--content/gpu/gpu_info_collector_android.cc4
-rw-r--r--gpu/command_buffer/service/feature_info.cc5
-rw-r--r--gpu/command_buffer/service/gl_context_virtual.cc4
-rw-r--r--gpu/command_buffer/service/gl_context_virtual.h1
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc6
-rw-r--r--gpu/command_buffer/service/gpu_driver_bug_workaround_type.h2
-rw-r--r--ui/gl/gl_context.cc4
-rw-r--r--ui/gl/gl_context.h4
-rw-r--r--ui/gl/gl_context_egl.cc48
-rw-r--r--ui/gl/gl_context_egl.h4
-rw-r--r--ui/gl/gl_surface.cc9
-rw-r--r--ui/gl/gl_surface.h4
-rw-r--r--ui/gl/gl_surface_egl.cc9
-rw-r--r--ui/gl/gl_surface_egl.h1
14 files changed, 103 insertions, 2 deletions
diff --git a/content/gpu/gpu_info_collector_android.cc b/content/gpu/gpu_info_collector_android.cc
index 3197414..902bc8c 100644
--- a/content/gpu/gpu_info_collector_android.cc
+++ b/content/gpu/gpu_info_collector_android.cc
@@ -74,6 +74,7 @@ bool CollectBasicGraphicsInfo(content::GPUInfo* gpu_info) {
bool is_arm = vendor.find("arm") != std::string::npos;
bool is_qualcomm = vendor.find("qualcomm") != std::string::npos;
bool is_mali_t604 = is_arm && renderer.find("mali-t604") != std::string::npos;
+ bool is_hisilicon = vendor.find("hisilicon") != std::string::npos;
base::android::BuildInfo* build_info =
base::android::BuildInfo::GetInstance();
@@ -91,7 +92,8 @@ bool CollectBasicGraphicsInfo(content::GPUInfo* gpu_info) {
// IMG: avoid context switching perf problems, crashes with share groups
// Mali-T604: http://crbug.com/154715
// QualComm, NVIDIA: Crashes with share groups
- if (is_img || is_mali_t604 || is_nexus7 || (is_qualcomm && sdk_int != 16)) {
+ if (is_hisilicon || is_img || is_mali_t604 || is_nexus7
+ || (is_qualcomm && sdk_int != 16)) {
CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableVirtualGLContexts);
}
diff --git a/gpu/command_buffer/service/feature_info.cc b/gpu/command_buffer/service/feature_info.cc
index d9df6f6..aad133e 100644
--- a/gpu/command_buffer/service/feature_info.cc
+++ b/gpu/command_buffer/service/feature_info.cc
@@ -191,6 +191,7 @@ void FeatureInfo::AddFeatures(const CommandLine& command_line) {
bool is_qualcomm = false;
bool is_imagination = false;
bool is_arm = false;
+ bool is_hisilicon = false;
const char* gl_strings[2];
gl_strings[0] = reinterpret_cast<const char*>(glGetString(GL_VENDOR));
gl_strings[1] = reinterpret_cast<const char*>(glGetString(GL_RENDERER));
@@ -208,6 +209,7 @@ void FeatureInfo::AddFeatures(const CommandLine& command_line) {
is_qualcomm |= string_set.Contains("qualcomm");
is_imagination |= string_set.Contains("imagination");
is_arm |= string_set.Contains("arm");
+ is_hisilicon |= string_set.Contains("hisilicon");
}
}
@@ -221,6 +223,9 @@ void FeatureInfo::AddFeatures(const CommandLine& command_line) {
workarounds_.flush_on_context_switch = true;
workarounds_.delete_instead_of_resize_fbo = true;
}
+ if (is_hisilicon) {
+ workarounds_.makecurrent_recreates_surfaces = true;
+ }
#if defined(OS_MACOSX)
workarounds_.needs_offscreen_buffer_workaround = is_nvidia;
workarounds_.needs_glsl_built_in_function_emulation = is_amd;
diff --git a/gpu/command_buffer/service/gl_context_virtual.cc b/gpu/command_buffer/service/gl_context_virtual.cc
index bc8c820..71c4762 100644
--- a/gpu/command_buffer/service/gl_context_virtual.cc
+++ b/gpu/command_buffer/service/gl_context_virtual.cc
@@ -103,6 +103,10 @@ bool GLContextVirtual::WasAllocatedUsingRobustnessExtension() {
return shared_context_->WasAllocatedUsingRobustnessExtension();
}
+void GLContextVirtual::SetRecreateSurfaceOnMakeCurrent() {
+ shared_context_->SetRecreateSurfaceOnMakeCurrent();
+}
+
GLContextVirtual::~GLContextVirtual() {
Destroy();
}
diff --git a/gpu/command_buffer/service/gl_context_virtual.h b/gpu/command_buffer/service/gl_context_virtual.h
index 9013a5f..026aca0 100644
--- a/gpu/command_buffer/service/gl_context_virtual.h
+++ b/gpu/command_buffer/service/gl_context_virtual.h
@@ -48,6 +48,7 @@ class GPU_EXPORT GLContextVirtual : public gfx::GLContext {
virtual bool GetTotalGpuMemory(size_t* bytes) OVERRIDE;
virtual void SetSafeToForceGpuSwitch() OVERRIDE;
virtual bool WasAllocatedUsingRobustnessExtension() OVERRIDE;
+ virtual void SetRecreateSurfaceOnMakeCurrent() OVERRIDE;
protected:
virtual ~GLContextVirtual();
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 38be722..b50437a 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -2532,6 +2532,12 @@ bool GLES2DecoderImpl::Initialize(
glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
}
+#if defined(OS_ANDROID)
+ if (feature_info_->workarounds().makecurrent_recreates_surfaces) {
+ context_->SetRecreateSurfaceOnMakeCurrent();
+ }
+#endif
+
// Only compositor contexts are known to use only the subset of GL
// that can be safely migrated between the iGPU and the dGPU. Mark
// those contexts as safe to forcibly transition between the GPUs.
diff --git a/gpu/command_buffer/service/gpu_driver_bug_workaround_type.h b/gpu/command_buffer/service/gpu_driver_bug_workaround_type.h
index 0478b28..fa71504 100644
--- a/gpu/command_buffer/service/gpu_driver_bug_workaround_type.h
+++ b/gpu/command_buffer/service/gpu_driver_bug_workaround_type.h
@@ -28,6 +28,8 @@
exit_on_context_lost) \
GPU_OP(FLUSH_ON_CONTEXT_SWITCH, \
flush_on_context_switch) \
+ GPU_OP(MAKECURRENT_RECREATES_SURFACES, \
+ makecurrent_recreates_surfaces) \
GPU_OP(MAX_CUBE_MAP_TEXTURE_SIZE_LIMIT_1024, \
max_cube_map_texture_size_limit_1024) \
GPU_OP(MAX_CUBE_MAP_TEXTURE_SIZE_LIMIT_4096, \
diff --git a/ui/gl/gl_context.cc b/ui/gl/gl_context.cc
index 703bfc2..74c95f5 100644
--- a/ui/gl/gl_context.cc
+++ b/ui/gl/gl_context.cc
@@ -45,6 +45,10 @@ bool GLContext::GetTotalGpuMemory(size_t* bytes) {
void GLContext::SetSafeToForceGpuSwitch() {
}
+void GLContext::SetRecreateSurfaceOnMakeCurrent() {
+ NOTIMPLEMENTED();
+}
+
std::string GLContext::GetExtensions() {
DCHECK(IsCurrent(NULL));
const char* ext = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
diff --git a/ui/gl/gl_context.h b/ui/gl/gl_context.h
index 7300cdb..7645a29 100644
--- a/ui/gl/gl_context.h
+++ b/ui/gl/gl_context.h
@@ -65,6 +65,10 @@ class GL_EXPORT GLContext : public base::RefCounted<GLContext> {
// transitioning can cause corruption and hangs (OS X only).
virtual void SetSafeToForceGpuSwitch();
+ // Indicate that the real context switches should recreate the surface
+ // (For an Android work-around only).
+ virtual void SetRecreateSurfaceOnMakeCurrent();
+
// Returns whether the current context supports the named extension. The
// context must be current.
bool HasExtension(const char* name);
diff --git a/ui/gl/gl_context_egl.cc b/ui/gl/gl_context_egl.cc
index 52c60e2..196438c 100644
--- a/ui/gl/gl_context_egl.cc
+++ b/ui/gl/gl_context_egl.cc
@@ -28,7 +28,8 @@ GLContextEGL::GLContextEGL(GLShareGroup* share_group)
: GLContext(share_group),
context_(NULL),
display_(NULL),
- config_(NULL) {
+ config_(NULL),
+ recreate_surface_on_makecurrent_(false) {
}
bool GLContextEGL::Initialize(
@@ -112,6 +113,11 @@ bool GLContextEGL::MakeCurrent(GLSurface* surface) {
return false;
}
+#if defined(OS_ANDROID)
+ if (!RecreateSurfaceIfNeeded(surface))
+ return false;
+#endif
+
if (!surface->OnMakeCurrent(this)) {
LOG(ERROR) << "Could not make current.";
return false;
@@ -121,6 +127,46 @@ bool GLContextEGL::MakeCurrent(GLSurface* surface) {
return true;
}
+void GLContextEGL::SetRecreateSurfaceOnMakeCurrent() {
+ recreate_surface_on_makecurrent_ = true;
+}
+
+bool GLContextEGL::RecreateSurfaceIfNeeded(GLSurface* surface) {
+ if (!recreate_surface_on_makecurrent_ ||
+ !surface ||
+ surface->IsOffscreen() ||
+ surface->GetBackingFrameBufferObject())
+ 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..a4f0cbf 100644
--- a/ui/gl/gl_context_egl.h
+++ b/ui/gl/gl_context_egl.h
@@ -35,6 +35,9 @@ class GLContextEGL : public GLContext {
virtual std::string GetExtensions() OVERRIDE;
virtual bool WasAllocatedUsingRobustnessExtension() OVERRIDE;
virtual bool GetTotalGpuMemory(size_t* bytes) OVERRIDE;
+ virtual void SetRecreateSurfaceOnMakeCurrent() OVERRIDE;
+
+ bool RecreateSurfaceIfNeeded(GLSurface* surface);
protected:
virtual ~GLContextEGL();
@@ -43,6 +46,7 @@ class GLContextEGL : public GLContext {
EGLContext context_;
EGLDisplay display_;
EGLConfig config_;
+ bool recreate_surface_on_makecurrent_;
DISALLOW_COPY_AND_ASSIGN(GLContextEGL);
};
diff --git a/ui/gl/gl_surface.cc b/ui/gl/gl_surface.cc
index 0feeb34..f09aa35 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;
}
@@ -185,6 +190,10 @@ bool GLSurfaceAdapter::Resize(const gfx::Size& size) {
return surface_->Resize(size);
}
+bool GLSurfaceAdapter::Recreate() {
+ return surface_->Recreate();
+}
+
bool GLSurfaceAdapter::DeferDraws() {
return surface_->DeferDraws();
}
diff --git a/ui/gl/gl_surface.h b/ui/gl/gl_surface.h
index 6924685..b026bc7 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.
@@ -137,6 +140,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;
diff --git a/ui/gl/gl_surface_egl.cc b/ui/gl/gl_surface_egl.cc
index 3b81daf..ae22a28 100644
--- a/ui/gl/gl_surface_egl.cc
+++ b/ui/gl/gl_surface_egl.cc
@@ -411,6 +411,15 @@ bool NativeViewGLSurfaceEGL::Resize(const gfx::Size& size) {
return true;
}
+bool NativeViewGLSurfaceEGL::Recreate() {
+ Destroy();
+ if (!Initialize()) {
+ LOG(ERROR) << "Failed to create surface.";
+ return false;
+ }
+ return true;
+}
+
EGLSurface NativeViewGLSurfaceEGL::GetHandle() {
return surface_;
}
diff --git a/ui/gl/gl_surface_egl.h b/ui/gl/gl_surface_egl.h
index 17e6e94..6440504 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;