| 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
|
|
|