| // Copyright 2018 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "android_webview/test/shell/src/draw_fn/allocator.h" |
| |
| #include "android_webview/public/browser/draw_fn.h" |
| #include "base/logging.h" |
| #include "base/no_destructor.h" |
| #include "base/notreached.h" |
| |
| namespace draw_fn { |
| |
| namespace { |
| |
| bool g_use_vulkan = false; |
| |
| AwDrawFnRenderMode QueryRenderMode() { |
| return g_use_vulkan ? AW_DRAW_FN_RENDER_MODE_VULKAN |
| : AW_DRAW_FN_RENDER_MODE_OPENGL_ES; |
| } |
| |
| int CreateFunctor(void* data, AwDrawFnFunctorCallbacks* functor_callbacks) { |
| NOTREACHED(); |
| } |
| |
| int CreateFunctor_v3(void* data, |
| int version, |
| AwDrawFnFunctorCallbacks* functor_callbacks) { |
| DCHECK_GE(version, 3); |
| return Allocator::Get()->allocate(data, functor_callbacks); |
| } |
| |
| void ReleaseFunctor(int functor) { |
| Allocator::Get()->MarkReleasedByFunctor(functor); |
| } |
| |
| void ReportRenderingThreads(int functor, const pid_t* thread_ids, size_t size) { |
| } |
| |
| } // namespace |
| |
| void SetDrawFnUseVulkan(bool use_vulkan) { |
| g_use_vulkan = use_vulkan; |
| } |
| |
| AwDrawFnFunctionTable* GetDrawFnFunctionTable() { |
| static AwDrawFnFunctionTable table{ |
| kAwDrawFnVersion, &QueryRenderMode, &CreateFunctor, |
| &ReleaseFunctor, &CreateFunctor_v3, &ReportRenderingThreads}; |
| return &table; |
| } |
| |
| FunctorData::FunctorData() = default; |
| FunctorData::~FunctorData() = default; |
| FunctorData::FunctorData(FunctorData&&) = default; |
| FunctorData& FunctorData::operator=(FunctorData&&) = default; |
| |
| FunctorData::FunctorData(int functor, |
| void* data, |
| AwDrawFnFunctorCallbacks* functor_callbacks) |
| : functor(functor), data(data), functor_callbacks(functor_callbacks) {} |
| |
| // static |
| Allocator* Allocator::Get() { |
| static base::NoDestructor<Allocator> map; |
| return map.get(); |
| } |
| |
| Allocator::Allocator() = default; |
| Allocator::~Allocator() = default; |
| |
| int Allocator::allocate(void* data, |
| AwDrawFnFunctorCallbacks* functor_callbacks) { |
| base::AutoLock lock(lock_); |
| int functor = next_functor_++; |
| map_.emplace(functor, FunctorData(functor, data, functor_callbacks)); |
| return functor; |
| } |
| |
| FunctorData& Allocator::get(int functor) { |
| base::AutoLock lock(lock_); |
| auto itr = map_.find(functor); |
| CHECK(itr != map_.end()); |
| return itr->second; |
| } |
| |
| void Allocator::MarkReleasedByFunctor(int functor) { |
| base::AutoLock lock(lock_); |
| auto itr = map_.find(functor); |
| CHECK(itr != map_.end()); |
| DCHECK(!itr->second.released_by_functor); |
| itr->second.released_by_functor = true; |
| MaybeReleaseFunctorAlreadyLocked(functor); |
| } |
| |
| void Allocator::MarkReleasedByManager(int functor) { |
| base::AutoLock lock(lock_); |
| auto itr = map_.find(functor); |
| CHECK(itr != map_.end()); |
| DCHECK(!itr->second.released_by_manager); |
| MaybeReleaseFunctorAlreadyLocked(functor); |
| } |
| |
| void Allocator::MaybeReleaseFunctorAlreadyLocked(int functor) { |
| lock_.AssertAcquired(); |
| auto itr = map_.find(functor); |
| const FunctorData& data = itr->second; |
| if (data.released_by_functor && data.released_by_manager) { |
| data.functor_callbacks->on_destroyed(data.functor, data.data); |
| map_.erase(itr); |
| } |
| } |
| |
| } // namespace draw_fn |