summaryrefslogtreecommitdiffstats
path: root/chromium/content/browser/renderer_host/compositing_iosurface_context_mac.mm
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/content/browser/renderer_host/compositing_iosurface_context_mac.mm')
-rw-r--r--chromium/content/browser/renderer_host/compositing_iosurface_context_mac.mm138
1 files changed, 70 insertions, 68 deletions
diff --git a/chromium/content/browser/renderer_host/compositing_iosurface_context_mac.mm b/chromium/content/browser/renderer_host/compositing_iosurface_context_mac.mm
index 4c6cbf1c12a..a66bf5022d3 100644
--- a/chromium/content/browser/renderer_host/compositing_iosurface_context_mac.mm
+++ b/chromium/content/browser/renderer_host/compositing_iosurface_context_mac.mm
@@ -12,6 +12,8 @@
#include "base/debug/trace_event.h"
#include "base/logging.h"
#include "content/browser/renderer_host/compositing_iosurface_shader_programs_mac.h"
+#include "content/browser/gpu/gpu_data_manager_impl.h"
+#include "ui/base/ui_base_switches.h"
#include "ui/gl/gl_switches.h"
#include "ui/gl/gpu_switching_manager.h"
@@ -25,65 +27,68 @@ CompositingIOSurfaceContext::Get(int window_number) {
// Return the context for this window_number, if it exists.
WindowMap::iterator found = window_map()->find(window_number);
if (found != window_map()->end()) {
- DCHECK(found->second->can_be_shared_);
+ DCHECK(!found->second->poisoned_);
return found->second;
}
- std::vector<NSOpenGLPixelFormatAttribute> attributes;
- attributes.push_back(NSOpenGLPFADoubleBuffer);
- // We don't need a depth buffer - try setting its size to 0...
- attributes.push_back(NSOpenGLPFADepthSize); attributes.push_back(0);
- if (ui::GpuSwitchingManager::GetInstance()->SupportsDualGpus())
- attributes.push_back(NSOpenGLPFAAllowOfflineRenderers);
- attributes.push_back(0);
-
- base::scoped_nsobject<NSOpenGLPixelFormat> glPixelFormat(
- [[NSOpenGLPixelFormat alloc] initWithAttributes:&attributes.front()]);
- if (!glPixelFormat) {
- LOG(ERROR) << "NSOpenGLPixelFormat initWithAttributes failed";
+ static bool is_vsync_disabled =
+ CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableGpuVsync);
+
+ base::ScopedTypeRef<CGLContextObj> cgl_context_strong;
+ CGLContextObj cgl_context = NULL;
+ CGLError error = kCGLNoError;
+
+ // Create the pixel format object for the context.
+ std::vector<CGLPixelFormatAttribute> attribs;
+ attribs.push_back(kCGLPFADepthSize);
+ attribs.push_back(static_cast<CGLPixelFormatAttribute>(0));
+ if (ui::GpuSwitchingManager::GetInstance()->SupportsDualGpus()) {
+ attribs.push_back(kCGLPFAAllowOfflineRenderers);
+ attribs.push_back(static_cast<CGLPixelFormatAttribute>(1));
+ }
+ attribs.push_back(static_cast<CGLPixelFormatAttribute>(0));
+ GLint number_virtual_screens = 0;
+ base::ScopedTypeRef<CGLPixelFormatObj> pixel_format;
+ error = CGLChoosePixelFormat(&attribs.front(),
+ pixel_format.InitializeInto(),
+ &number_virtual_screens);
+ if (error != kCGLNoError) {
+ LOG(ERROR) << "Failed to create pixel format object.";
return NULL;
}
// Create all contexts in the same share group so that the textures don't
// need to be recreated when transitioning contexts.
- NSOpenGLContext* share_context = nil;
+ CGLContextObj share_context = NULL;
if (!window_map()->empty())
- share_context = window_map()->begin()->second->nsgl_context();
- base::scoped_nsobject<NSOpenGLContext> nsgl_context(
- [[NSOpenGLContext alloc] initWithFormat:glPixelFormat
- shareContext:share_context]);
- if (!nsgl_context) {
- LOG(ERROR) << "NSOpenGLContext initWithFormat failed";
+ share_context = window_map()->begin()->second->cgl_context();
+ error = CGLCreateContext(
+ pixel_format, share_context, cgl_context_strong.InitializeInto());
+ if (error != kCGLNoError) {
+ LOG(ERROR) << "Failed to create context object.";
return NULL;
}
+ cgl_context = cgl_context_strong;
- CGLContextObj cgl_context = (CGLContextObj)[nsgl_context CGLContextObj];
- if (!cgl_context) {
- LOG(ERROR) << "CGLContextObj failed";
- return NULL;
- }
-
- // Draw at beam vsync.
- bool is_vsync_disabled =
- CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableGpuVsync);
- GLint swapInterval = is_vsync_disabled ? 0 : 1;
- [nsgl_context setValues:&swapInterval forParameter:NSOpenGLCPSwapInterval];
+ // Note that VSync is ignored because CoreAnimation will automatically
+ // rate limit draws.
// Prepare the shader program cache. Precompile the shader programs
// needed to draw the IO Surface for non-offscreen contexts.
- CGLSetCurrentContext(cgl_context);
- scoped_ptr<CompositingIOSurfaceShaderPrograms> shader_program_cache(
- new CompositingIOSurfaceShaderPrograms());
bool prepared = false;
- if (window_number == kOffscreenContextWindowNumber) {
- prepared = true;
- } else {
- prepared = (
- shader_program_cache->UseBlitProgram() &&
- shader_program_cache->UseSolidWhiteProgram());
+ scoped_ptr<CompositingIOSurfaceShaderPrograms> shader_program_cache;
+ {
+ gfx::ScopedCGLSetCurrentContext scoped_set_current_context(cgl_context);
+ shader_program_cache.reset(new CompositingIOSurfaceShaderPrograms());
+ if (window_number == kOffscreenContextWindowNumber) {
+ prepared = true;
+ } else {
+ prepared = (
+ shader_program_cache->UseBlitProgram() &&
+ shader_program_cache->UseSolidWhiteProgram());
+ }
+ glUseProgram(0u);
}
- glUseProgram(0u);
- CGLSetCurrentContext(0);
if (!prepared) {
LOG(ERROR) << "IOSurface failed to compile/link required shader programs.";
return NULL;
@@ -91,46 +96,50 @@ CompositingIOSurfaceContext::Get(int window_number) {
return new CompositingIOSurfaceContext(
window_number,
- nsgl_context.release(),
+ cgl_context_strong,
cgl_context,
is_vsync_disabled,
shader_program_cache.Pass());
}
-// static
-void CompositingIOSurfaceContext::MarkExistingContextsAsNotShareable() {
+void CompositingIOSurfaceContext::PoisonContextAndSharegroup() {
+ if (poisoned_)
+ return;
+
for (WindowMap::iterator it = window_map()->begin();
it != window_map()->end();
++it) {
- it->second->can_be_shared_ = false;
+ it->second->poisoned_ = true;
}
window_map()->clear();
}
CompositingIOSurfaceContext::CompositingIOSurfaceContext(
int window_number,
- NSOpenGLContext* nsgl_context,
+ base::ScopedTypeRef<CGLContextObj> cgl_context_strong,
CGLContextObj cgl_context,
bool is_vsync_disabled,
scoped_ptr<CompositingIOSurfaceShaderPrograms> shader_program_cache)
: window_number_(window_number),
- nsgl_context_(nsgl_context),
+ cgl_context_strong_(cgl_context_strong),
cgl_context_(cgl_context),
is_vsync_disabled_(is_vsync_disabled),
shader_program_cache_(shader_program_cache.Pass()),
- can_be_shared_(true),
- initialized_is_intel_(false),
- is_intel_(false),
- screen_(0) {
+ poisoned_(false) {
DCHECK(window_map()->find(window_number_) == window_map()->end());
window_map()->insert(std::make_pair(window_number_, this));
+
+ GpuDataManager::GetInstance()->AddObserver(this);
}
CompositingIOSurfaceContext::~CompositingIOSurfaceContext() {
- CGLSetCurrentContext(cgl_context_);
- shader_program_cache_->Reset();
- CGLSetCurrentContext(0);
- if (can_be_shared_) {
+ GpuDataManager::GetInstance()->RemoveObserver(this);
+
+ {
+ gfx::ScopedCGLSetCurrentContext scoped_set_current_context(cgl_context_);
+ shader_program_cache_->Reset();
+ }
+ if (!poisoned_) {
DCHECK(window_map()->find(window_number_) != window_map()->end());
DCHECK(window_map()->find(window_number_)->second == this);
window_map()->erase(window_number_);
@@ -141,18 +150,11 @@ CompositingIOSurfaceContext::~CompositingIOSurfaceContext() {
}
}
-bool CompositingIOSurfaceContext::IsVendorIntel() {
- GLint screen;
- CGLGetVirtualScreen(cgl_context(), &screen);
- if (screen != screen_)
- initialized_is_intel_ = false;
- screen_ = screen;
- if (!initialized_is_intel_) {
- is_intel_ = strstr(reinterpret_cast<const char*>(glGetString(GL_VENDOR)),
- "Intel") != NULL;
- initialized_is_intel_ = true;
- }
- return is_intel_;
+void CompositingIOSurfaceContext::OnGpuSwitching() {
+ // Recreate all browser-side GL contexts whenever the GPU switches. If this
+ // is not done, performance will suffer.
+ // http://crbug.com/361493
+ PoisonContextAndSharegroup();
}
// static