diff options
-rw-r--r-- | content/gpu/gpu_info_collector_android.cc | 4 | ||||
-rw-r--r-- | gpu/command_buffer/service/feature_info.cc | 5 | ||||
-rw-r--r-- | gpu/command_buffer/service/gl_context_virtual.cc | 4 | ||||
-rw-r--r-- | gpu/command_buffer/service/gl_context_virtual.h | 1 | ||||
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder.cc | 6 | ||||
-rw-r--r-- | gpu/command_buffer/service/gpu_driver_bug_workaround_type.h | 2 | ||||
-rw-r--r-- | ui/gl/gl_context.cc | 4 | ||||
-rw-r--r-- | ui/gl/gl_context.h | 4 | ||||
-rw-r--r-- | ui/gl/gl_context_egl.cc | 48 | ||||
-rw-r--r-- | ui/gl/gl_context_egl.h | 4 | ||||
-rw-r--r-- | ui/gl/gl_surface.cc | 9 | ||||
-rw-r--r-- | ui/gl/gl_surface.h | 4 | ||||
-rw-r--r-- | ui/gl/gl_surface_egl.cc | 9 | ||||
-rw-r--r-- | ui/gl/gl_surface_egl.h | 1 |
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; |