Home | History | Annotate | Download | only in resources
      1 // Copyright 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "cc/resources/texture_mailbox_deleter.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/location.h"
      9 #include "base/memory/weak_ptr.h"
     10 #include "base/single_thread_task_runner.h"
     11 #include "cc/output/context_provider.h"
     12 #include "cc/resources/single_release_callback.h"
     13 #include "gpu/command_buffer/client/gles2_interface.h"
     14 
     15 namespace cc {
     16 
     17 static void DeleteTextureOnImplThread(
     18     const scoped_refptr<ContextProvider>& context_provider,
     19     unsigned texture_id,
     20     uint32 sync_point,
     21     bool is_lost) {
     22   if (sync_point)
     23     context_provider->ContextGL()->WaitSyncPointCHROMIUM(sync_point);
     24   context_provider->ContextGL()->DeleteTextures(1, &texture_id);
     25 }
     26 
     27 static void PostTaskFromMainToImplThread(
     28     scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner,
     29     ReleaseCallback run_impl_callback,
     30     unsigned sync_point,
     31     bool is_lost) {
     32   // This posts the task to RunDeleteTextureOnImplThread().
     33   impl_task_runner->PostTask(
     34       FROM_HERE, base::Bind(run_impl_callback, sync_point, is_lost));
     35 }
     36 
     37 TextureMailboxDeleter::TextureMailboxDeleter(
     38     const scoped_refptr<base::SingleThreadTaskRunner>& task_runner)
     39     : impl_task_runner_(task_runner), weak_ptr_factory_(this) {}
     40 
     41 TextureMailboxDeleter::~TextureMailboxDeleter() {
     42   for (size_t i = 0; i < impl_callbacks_.size(); ++i)
     43     impl_callbacks_.at(i)->Run(0, true);
     44 }
     45 
     46 scoped_ptr<SingleReleaseCallback> TextureMailboxDeleter::GetReleaseCallback(
     47     const scoped_refptr<ContextProvider>& context_provider,
     48     unsigned texture_id) {
     49   // This callback owns a reference on the |context_provider|. It must be
     50   // destroyed on the impl thread. Upon destruction of this class, the
     51   // callback must immediately be destroyed.
     52   scoped_ptr<SingleReleaseCallback> impl_callback =
     53       SingleReleaseCallback::Create(base::Bind(&DeleteTextureOnImplThread,
     54                                                context_provider,
     55                                                texture_id));
     56 
     57   impl_callbacks_.push_back(impl_callback.Pass());
     58 
     59   // The raw pointer to the impl-side callback is valid as long as this
     60   // class is alive. So we guard it with a WeakPtr.
     61   ReleaseCallback run_impl_callback(
     62       base::Bind(&TextureMailboxDeleter::RunDeleteTextureOnImplThread,
     63                  weak_ptr_factory_.GetWeakPtr(),
     64                  impl_callbacks_.back()));
     65 
     66   // Provide a callback for the main thread that posts back to the impl
     67   // thread.
     68   scoped_ptr<SingleReleaseCallback> main_callback =
     69       SingleReleaseCallback::Create(base::Bind(
     70           &PostTaskFromMainToImplThread, impl_task_runner_, run_impl_callback));
     71 
     72   return main_callback.Pass();
     73 }
     74 
     75 void TextureMailboxDeleter::RunDeleteTextureOnImplThread(
     76     SingleReleaseCallback* impl_callback,
     77     unsigned sync_point,
     78     bool is_lost) {
     79   for (size_t i = 0; i < impl_callbacks_.size(); ++i) {
     80     if (impl_callbacks_.at(i) == impl_callback) {
     81       // Run the callback, then destroy it here on the impl thread.
     82       impl_callbacks_.at(i)->Run(sync_point, is_lost);
     83       impl_callbacks_.erase(impl_callbacks_.begin() + i);
     84       return;
     85     }
     86   }
     87 
     88   NOTREACHED() << "The Callback returned by GetDeleteCallback() was called "
     89                << "more than once.";
     90 }
     91 
     92 }  // namespace cc
     93