Fix several leaks in the Sky compositor

When tearing down the Sky compostior, we need to destroy the GL context and all
the textures in the resource manager.

R=ojan@chromium.org

Review URL: https://codereview.chromium.org/761503004
diff --git a/mojo/gpu/BUILD.gn b/mojo/gpu/BUILD.gn
index 973168d..070c330 100644
--- a/mojo/gpu/BUILD.gn
+++ b/mojo/gpu/BUILD.gn
@@ -6,6 +6,8 @@
   sources = [
     "gl_context.cc",
     "gl_context.h",
+    "gl_context_owner.cc",
+    "gl_context_owner.h",
     "gl_texture.cc",
     "gl_texture.h",
   ]
diff --git a/mojo/gpu/gl_context_owner.cc b/mojo/gpu/gl_context_owner.cc
new file mode 100644
index 0000000..81d7d33
--- /dev/null
+++ b/mojo/gpu/gl_context_owner.cc
@@ -0,0 +1,19 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "mojo/gpu/gl_context_owner.h"
+
+#include "mojo/gpu/gl_context.h"
+
+namespace mojo {
+
+GLContextOwner::GLContextOwner(mojo::Shell* shell)
+    : context_(mojo::GLContext::Create(shell)) {
+}
+
+GLContextOwner::~GLContextOwner() {
+  context_->Destroy();
+}
+
+}  // namespace mojo
diff --git a/mojo/gpu/gl_context_owner.h b/mojo/gpu/gl_context_owner.h
new file mode 100644
index 0000000..872729a
--- /dev/null
+++ b/mojo/gpu/gl_context_owner.h
@@ -0,0 +1,29 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MOJO_GPU_GL_CONTEXT_OWNER_H_
+#define MOJO_GPU_GL_CONTEXT_OWNER_H_
+
+#include "base/memory/weak_ptr.h"
+
+namespace mojo {
+class GLContext;
+class Shell;
+
+class GLContextOwner {
+ public:
+  explicit GLContextOwner(mojo::Shell* shell);
+  ~GLContextOwner();
+
+  const base::WeakPtr<mojo::GLContext>& context() const { return context_; }
+
+ private:
+  base::WeakPtr<mojo::GLContext> context_;
+
+  DISALLOW_COPY_AND_ASSIGN(GLContextOwner);
+};
+
+}  // namespace mojo
+
+#endif  // MOJO_GPU_GL_CONTEXT_OWNER_H_
diff --git a/sky/compositor/layer_host.cc b/sky/compositor/layer_host.cc
index a4d5a08..ef6b543 100644
--- a/sky/compositor/layer_host.cc
+++ b/sky/compositor/layer_host.cc
@@ -19,9 +19,9 @@
       state_(kWaitingForSurfaceService),
       frame_requested_(false),
       surface_holder_(this, client->GetShell()),
-      gl_context_(mojo::GLContext::Create(client->GetShell())),
-      ganesh_context_(gl_context_),
-      resource_manager_(gl_context_),
+      gl_context_owner_(client->GetShell()),
+      ganesh_context_(gl_context()),
+      resource_manager_(gl_context()),
       weak_factory_(this) {
 }
 
diff --git a/sky/compositor/layer_host.h b/sky/compositor/layer_host.h
index 2f8ccdb..0b9616c 100644
--- a/sky/compositor/layer_host.h
+++ b/sky/compositor/layer_host.h
@@ -8,6 +8,7 @@
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/weak_ptr.h"
+#include "mojo/gpu/gl_context_owner.h"
 #include "mojo/skia/ganesh_context.h"
 #include "sky/compositor/layer_host_client.h"
 #include "sky/compositor/resource_manager.h"
@@ -26,7 +27,7 @@
   LayerHostClient* client() const { return client_; }
 
   const base::WeakPtr<mojo::GLContext>& gl_context() const {
-    return gl_context_;
+    return gl_context_owner_.context();
   }
 
   mojo::GaneshContext* ganesh_context() const {
@@ -63,7 +64,7 @@
   State state_;
   bool frame_requested_;
   SurfaceHolder surface_holder_;
-  base::WeakPtr<mojo::GLContext> gl_context_;
+  mojo::GLContextOwner gl_context_owner_;
   mojo::GaneshContext ganesh_context_;
   ResourceManager resource_manager_;
   scoped_refptr<Layer> root_layer_;
diff --git a/sky/compositor/resource_manager.cc b/sky/compositor/resource_manager.cc
index 5fee461..fe6dc0e 100644
--- a/sky/compositor/resource_manager.cc
+++ b/sky/compositor/resource_manager.cc
@@ -9,6 +9,7 @@
 #endif
 
 #include "base/logging.h"
+#include "base/stl_util.h"
 #include "gpu/GLES2/gl2chromium.h"
 #include "gpu/GLES2/gl2extchromium.h"
 #include "mojo/converters/geometry/geometry_type_converters.h"
@@ -24,6 +25,8 @@
 }
 
 ResourceManager::~ResourceManager() {
+  STLDeleteContainerPairSecondPointers(resource_to_texture_map_.begin(),
+                                       resource_to_texture_map_.end());
 }
 
 scoped_ptr<mojo::GLTexture> ResourceManager::CreateTexture(
@@ -73,11 +76,14 @@
   for (size_t i = 0u; i < resources.size(); ++i) {
     mojo::ReturnedResourcePtr resource = resources[i].Pass();
     DCHECK_EQ(1, resource->count);
-    glWaitSyncPointCHROMIUM(resource->sync_point);
-    mojo::GLTexture* texture = resource_to_texture_map_[resource->id];
+    auto iter = resource_to_texture_map_.find(resource->id);
+    if (iter == resource_to_texture_map_.end())
+      continue;
+    mojo::GLTexture* texture = iter->second;
     DCHECK_NE(0u, texture->texture_id());
-    resource_to_texture_map_.erase(resource->id);
+    resource_to_texture_map_.erase(iter);
     // TODO(abarth): Consider recycling the texture.
+    glWaitSyncPointCHROMIUM(resource->sync_point);
     delete texture;
   }
 }