Index: content/browser/compositor/io_surface_context_mac.mm |
diff --git a/content/browser/compositor/io_surface_context_mac.mm b/content/browser/compositor/io_surface_context_mac.mm |
index 9d65fdc75aa078d0b076967de5f276a44f4f011f..623d5902e62fd9f0c9d0e0ae7bd0dc556bb5e2b4 100644 |
--- a/content/browser/compositor/io_surface_context_mac.mm |
+++ b/content/browser/compositor/io_surface_context_mac.mm |
@@ -20,12 +20,15 @@ |
// static |
scoped_refptr<IOSurfaceContext> |
-IOSurfaceContext::Get() { |
+IOSurfaceContext::Get(Type type) { |
TRACE_EVENT0("browser", "IOSurfaceContext::Get"); |
- // Return the context, if it exists. |
- if (current_context_) |
- return current_context_; |
+ // Return the context for this type, if it exists. |
+ TypeMap::iterator found = type_map()->find(type); |
+ if (found != type_map()->end()) { |
+ DCHECK(!found->second->poisoned_); |
+ return found->second; |
+ } |
base::ScopedTypeRef<CGLContextObj> cgl_context; |
CGLError error = kCGLNoError; |
@@ -49,28 +52,39 @@ |
return NULL; |
} |
- error = CGLCreateContext(pixel_format, NULL, cgl_context.InitializeInto()); |
+ // Create all contexts in the same share group so that the textures don't |
+ // need to be recreated when transitioning contexts. |
+ CGLContextObj share_context = NULL; |
+ if (!type_map()->empty()) |
+ share_context = type_map()->begin()->second->cgl_context(); |
+ error = CGLCreateContext( |
+ pixel_format, share_context, cgl_context.InitializeInto()); |
if (error != kCGLNoError) { |
LOG(ERROR) << "Failed to create context object."; |
return NULL; |
} |
- return new IOSurfaceContext(cgl_context); |
+ return new IOSurfaceContext(type, cgl_context); |
} |
void IOSurfaceContext::PoisonContextAndSharegroup() { |
if (poisoned_) |
return; |
- DCHECK(current_context_ == this); |
- current_context_ = NULL; |
- poisoned_ = true; |
+ |
+ for (TypeMap::iterator it = type_map()->begin(); |
+ it != type_map()->end(); |
+ ++it) { |
+ it->second->poisoned_ = true; |
+ } |
+ type_map()->clear(); |
} |
IOSurfaceContext::IOSurfaceContext( |
- base::ScopedTypeRef<CGLContextObj> cgl_context) |
- : cgl_context_(cgl_context), poisoned_(false) { |
- DCHECK(!current_context_); |
- current_context_ = this; |
+ Type type, base::ScopedTypeRef<CGLContextObj> cgl_context) |
+ : type_(type), cgl_context_(cgl_context), poisoned_(false) { |
+ DCHECK(type_map()->find(type_) == type_map()->end()); |
+ type_map()->insert(std::make_pair(type_, this)); |
+ |
GpuDataManager::GetInstance()->AddObserver(this); |
} |
@@ -78,10 +92,13 @@ |
GpuDataManager::GetInstance()->RemoveObserver(this); |
if (!poisoned_) { |
- DCHECK(current_context_ == this); |
- current_context_ = NULL; |
+ DCHECK(type_map()->find(type_) != type_map()->end()); |
+ DCHECK(type_map()->find(type_)->second == this); |
+ type_map()->erase(type_); |
} else { |
- DCHECK(current_context_ != this); |
+ TypeMap::const_iterator found = type_map()->find(type_); |
+ if (found != type_map()->end()) |
+ DCHECK(found->second != this); |
} |
} |
@@ -93,6 +110,13 @@ |
} |
// static |
-IOSurfaceContext* IOSurfaceContext::current_context_ = NULL; |
+IOSurfaceContext::TypeMap* |
+ IOSurfaceContext::type_map() { |
+ return type_map_.Pointer(); |
+} |
+ |
+// static |
+base::LazyInstance<IOSurfaceContext::TypeMap> |
+ IOSurfaceContext::type_map_; |
} // namespace content |