| Index: gpu/command_buffer/client/gles2_implementation.cc | 
| diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc | 
| index d2f959c11b23f2ce34f6cd3c01ac053595704877..1098a4030e0e60e9941e2b3b40fc4a984c717030 100644 | 
| --- a/gpu/command_buffer/client/gles2_implementation.cc | 
| +++ b/gpu/command_buffer/client/gles2_implementation.cc | 
| @@ -19,6 +19,7 @@ | 
| #include <string> | 
| #include "base/atomic_sequence_num.h" | 
| #include "base/compiler_specific.h" | 
| +#include "base/memory/ptr_util.h" | 
| #include "base/strings/string_split.h" | 
| #include "base/strings/stringprintf.h" | 
| #include "base/sys_info.h" | 
| @@ -51,6 +52,22 @@ namespace gles2 { | 
|  | 
| namespace { | 
|  | 
| +// Class that DCHECKs if it is destructed without first having Release called. | 
| +class ScopedVisibilityImpl : public ContextSupport::ScopedVisibility { | 
| + public: | 
| +  explicit ScopedVisibilityImpl(ContextSupport* context_support) | 
| +      : initial_context_support_(context_support) {} | 
| +  ~ScopedVisibilityImpl() { DCHECK(!initial_context_support_); } | 
| + | 
| +  void Release(ContextSupport* context_support) { | 
| +    DCHECK_EQ(initial_context_support_, context_support); | 
| +    initial_context_support_ = nullptr; | 
| +  } | 
| + | 
| + private: | 
| +  const ContextSupport* initial_context_support_; | 
| +}; | 
| + | 
| void CopyRectToBuffer(const void* pixels, | 
| uint32_t height, | 
| uint32_t unpadded_row_size, | 
| @@ -164,7 +181,6 @@ GLES2Implementation::GLES2Implementation( | 
| current_trace_stack_(0), | 
| gpu_control_(gpu_control), | 
| capabilities_(gpu_control->GetCapabilities()), | 
| -      aggressively_free_resources_(false), | 
| cached_extension_string_(nullptr), | 
| weak_ptr_factory_(this) { | 
| DCHECK(helper); | 
| @@ -412,11 +428,12 @@ void GLES2Implementation::SignalQuery(uint32_t query, | 
| callback)); | 
| } | 
|  | 
| -void GLES2Implementation::SetAggressivelyFreeResources( | 
| -    bool aggressively_free_resources) { | 
| -  TRACE_EVENT1("gpu", "GLES2Implementation::SetAggressivelyFreeResources", | 
| -               "aggressively_free_resources", aggressively_free_resources); | 
| -  aggressively_free_resources_ = aggressively_free_resources; | 
| +void GLES2Implementation::TrimResources() { | 
| +  TRACE_EVENT0("gpu", "GLES2Implementation::TrimResources"); | 
| + | 
| +  // Set aggressively_free_resources_ to true, which will cause us to free | 
| +  // resources when we call Flush or ShallowFlushCHROMIUM below. | 
| +  aggressively_free_resources_ = true; | 
|  | 
| if (aggressively_free_resources_ && helper_->HaveRingBuffer()) { | 
| // Ensure that we clean up as much cache memory as possible and fully flush. | 
| @@ -428,6 +445,10 @@ void GLES2Implementation::SetAggressivelyFreeResources( | 
| } else { | 
| ShallowFlushCHROMIUM(); | 
| } | 
| + | 
| +  // If we are not visible, continue freeing resources on subsequent flushes. | 
| +  // This will be set to false once we become visible. | 
| +  aggressively_free_resources_ = !AnyClientsVisible(); | 
| } | 
|  | 
| bool GLES2Implementation::OnMemoryDump( | 
| @@ -5861,18 +5882,24 @@ void GLES2Implementation::SetErrorMessageCallback( | 
| error_message_callback_ = callback; | 
| } | 
|  | 
| -void GLES2Implementation::SetClientVisible(int client_id, bool is_visible) { | 
| -  if (is_visible) { | 
| -    visible_clients_.insert(client_id); | 
| -  } else { | 
| -    auto found = visible_clients_.find(client_id); | 
| -    if (found != visible_clients_.end()) | 
| -      visible_clients_.erase(found); | 
| -  } | 
| +std::unique_ptr<ContextSupport::ScopedVisibility> | 
| +GLES2Implementation::ClientBecameVisible() { | 
| +  ++num_visible_clients_; | 
| +  // We are visible, ensure that we are no longer freeing resources on flush. | 
| +  aggressively_free_resources_ = false; | 
| +  return base::MakeUnique<ScopedVisibilityImpl>(this); | 
| +} | 
| + | 
| +void GLES2Implementation::ClientBecameNotVisible( | 
| +    std::unique_ptr<ScopedVisibility> visibility) { | 
| +  DCHECK(visibility); | 
| +  DCHECK_GT(num_visible_clients_, 0u); | 
| +  --num_visible_clients_; | 
| +  static_cast<ScopedVisibilityImpl*>(visibility.get())->Release(this); | 
| } | 
|  | 
| bool GLES2Implementation::AnyClientsVisible() const { | 
| -  return !visible_clients_.empty(); | 
| +  return num_visible_clients_ > 0; | 
| } | 
|  | 
| void GLES2Implementation::SetLostContextCallback( | 
|  |