123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536 |
- // Copyright 2013 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 "components/viz/test/test_context_provider.h"
- #include <stddef.h>
- #include <stdint.h>
- #include <limits>
- #include <memory>
- #include <set>
- #include <utility>
- #include <vector>
- #include "base/bind.h"
- #include "base/callback_helpers.h"
- #include "base/check.h"
- #include "base/notreached.h"
- #include "build/build_config.h"
- #include "components/viz/common/gpu/context_cache_controller.h"
- #include "components/viz/test/test_gles2_interface.h"
- #include "components/viz/test/test_raster_interface.h"
- #include "gpu/command_buffer/client/raster_implementation_gles.h"
- #include "gpu/config/skia_limits.h"
- #include "gpu/skia_bindings/grcontext_for_gles2_interface.h"
- #include "third_party/skia/include/gpu/GrDirectContext.h"
- #include "third_party/skia/include/gpu/gl/GrGLInterface.h"
- #include "ui/gfx/gpu_fence.h"
- #include "ui/gfx/gpu_memory_buffer.h"
- namespace viz {
- namespace {
- // Various tests rely on functionality (capabilities) enabled by these extension
- // strings.
- const char* const kExtensions[] = {"GL_EXT_stencil_wrap",
- "GL_EXT_texture_format_BGRA8888",
- "GL_OES_rgb8_rgba8",
- "GL_EXT_texture_norm16",
- "GL_CHROMIUM_framebuffer_multisample",
- "GL_CHROMIUM_renderbuffer_format_BGRA8888",
- "GL_OES_texture_half_float",
- "GL_OES_texture_half_float_linear",
- "GL_EXT_color_buffer_half_float"};
- class TestGLES2InterfaceForContextProvider : public TestGLES2Interface {
- public:
- TestGLES2InterfaceForContextProvider(
- std::string additional_extensions = std::string())
- : extension_string_(
- BuildExtensionString(std::move(additional_extensions))) {}
- TestGLES2InterfaceForContextProvider(
- const TestGLES2InterfaceForContextProvider&) = delete;
- TestGLES2InterfaceForContextProvider& operator=(
- const TestGLES2InterfaceForContextProvider&) = delete;
- ~TestGLES2InterfaceForContextProvider() override = default;
- // TestGLES2Interface:
- const GLubyte* GetString(GLenum name) override {
- switch (name) {
- case GL_EXTENSIONS:
- return reinterpret_cast<const GLubyte*>(extension_string_.c_str());
- case GL_VERSION:
- return reinterpret_cast<const GrGLubyte*>("4.0 Null GL");
- case GL_SHADING_LANGUAGE_VERSION:
- return reinterpret_cast<const GrGLubyte*>("4.20.8 Null GLSL");
- case GL_VENDOR:
- return reinterpret_cast<const GrGLubyte*>("Null Vendor");
- case GL_RENDERER:
- return reinterpret_cast<const GrGLubyte*>("The Null (Non-)Renderer");
- }
- return nullptr;
- }
- const GrGLubyte* GetStringi(GrGLenum name, GrGLuint i) override {
- if (name == GL_EXTENSIONS && i < std::size(kExtensions))
- return reinterpret_cast<const GLubyte*>(kExtensions[i]);
- return nullptr;
- }
- void GetIntegerv(GLenum name, GLint* params) override {
- switch (name) {
- case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
- *params = 8;
- return;
- case GL_MAX_RENDERBUFFER_SIZE:
- *params = 2048;
- break;
- case GL_MAX_TEXTURE_SIZE:
- *params = 2048;
- break;
- case GL_MAX_TEXTURE_IMAGE_UNITS:
- *params = 8;
- break;
- case GL_MAX_VERTEX_ATTRIBS:
- *params = 8;
- break;
- case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
- *params = 0;
- return;
- default:
- break;
- }
- TestGLES2Interface::GetIntegerv(name, params);
- }
- private:
- static std::string BuildExtensionString(std::string additional_extensions) {
- std::string extension_string = kExtensions[0];
- for (size_t i = 1; i < std::size(kExtensions); ++i) {
- extension_string += " ";
- extension_string += kExtensions[i];
- }
- if (!additional_extensions.empty()) {
- extension_string += " ";
- extension_string += additional_extensions;
- }
- return extension_string;
- }
- const std::string extension_string_;
- };
- } // namespace
- TestSharedImageInterface::TestSharedImageInterface() = default;
- TestSharedImageInterface::~TestSharedImageInterface() = default;
- gpu::Mailbox TestSharedImageInterface::CreateSharedImage(
- ResourceFormat format,
- const gfx::Size& size,
- const gfx::ColorSpace& color_space,
- GrSurfaceOrigin surface_origin,
- SkAlphaType alpha_type,
- uint32_t usage,
- gpu::SurfaceHandle surface_handle) {
- base::AutoLock locked(lock_);
- auto mailbox = gpu::Mailbox::GenerateForSharedImage();
- shared_images_.insert(mailbox);
- most_recent_size_ = size;
- return mailbox;
- }
- gpu::Mailbox TestSharedImageInterface::CreateSharedImage(
- ResourceFormat format,
- const gfx::Size& size,
- const gfx::ColorSpace& color_space,
- GrSurfaceOrigin surface_origin,
- SkAlphaType alpha_type,
- uint32_t usage,
- base::span<const uint8_t> pixel_data) {
- base::AutoLock locked(lock_);
- auto mailbox = gpu::Mailbox::GenerateForSharedImage();
- shared_images_.insert(mailbox);
- return mailbox;
- }
- gpu::Mailbox TestSharedImageInterface::CreateSharedImage(
- gfx::GpuMemoryBuffer* gpu_memory_buffer,
- gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
- gfx::BufferPlane plane,
- const gfx::ColorSpace& color_space,
- GrSurfaceOrigin surface_origin,
- SkAlphaType alpha_type,
- uint32_t usage) {
- base::AutoLock locked(lock_);
- auto mailbox = gpu::Mailbox::GenerateForSharedImage();
- shared_images_.insert(mailbox);
- most_recent_size_ = gpu_memory_buffer->GetSize();
- return mailbox;
- }
- std::vector<gpu::Mailbox>
- TestSharedImageInterface::CreateSharedImageVideoPlanes(
- gfx::GpuMemoryBuffer* gpu_memory_buffer,
- gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
- uint32_t usage) {
- base::AutoLock locked(lock_);
- auto mailboxes =
- std::vector<gpu::Mailbox>{gpu::Mailbox::GenerateForSharedImage(),
- gpu::Mailbox::GenerateForSharedImage()};
- shared_images_.insert(mailboxes[0]);
- shared_images_.insert(mailboxes[1]);
- most_recent_size_ = gpu_memory_buffer->GetSize();
- return mailboxes;
- }
- void TestSharedImageInterface::UpdateSharedImage(
- const gpu::SyncToken& sync_token,
- const gpu::Mailbox& mailbox) {
- base::AutoLock locked(lock_);
- DCHECK(shared_images_.find(mailbox) != shared_images_.end());
- }
- void TestSharedImageInterface::UpdateSharedImage(
- const gpu::SyncToken& sync_token,
- std::unique_ptr<gfx::GpuFence> acquire_fence,
- const gpu::Mailbox& mailbox) {
- base::AutoLock locked(lock_);
- DCHECK(shared_images_.find(mailbox) != shared_images_.end());
- }
- void TestSharedImageInterface::DestroySharedImage(
- const gpu::SyncToken& sync_token,
- const gpu::Mailbox& mailbox) {
- base::AutoLock locked(lock_);
- shared_images_.erase(mailbox);
- most_recent_destroy_token_ = sync_token;
- }
- gpu::SharedImageInterface::SwapChainMailboxes
- TestSharedImageInterface::CreateSwapChain(ResourceFormat format,
- const gfx::Size& size,
- const gfx::ColorSpace& color_space,
- GrSurfaceOrigin surface_origin,
- SkAlphaType alpha_type,
- uint32_t usage) {
- auto front_buffer = gpu::Mailbox::GenerateForSharedImage();
- auto back_buffer = gpu::Mailbox::GenerateForSharedImage();
- shared_images_.insert(front_buffer);
- shared_images_.insert(back_buffer);
- return {front_buffer, back_buffer};
- }
- void TestSharedImageInterface::PresentSwapChain(
- const gpu::SyncToken& sync_token,
- const gpu::Mailbox& mailbox) {}
- #if BUILDFLAG(IS_FUCHSIA)
- void TestSharedImageInterface::RegisterSysmemBufferCollection(
- gfx::SysmemBufferCollectionId id,
- zx::channel token,
- gfx::BufferFormat format,
- gfx::BufferUsage usage,
- bool register_with_image_pipe) {
- NOTREACHED();
- }
- void TestSharedImageInterface::ReleaseSysmemBufferCollection(
- gfx::SysmemBufferCollectionId id) {
- NOTREACHED();
- }
- #endif // BUILDFLAG(IS_FUCHSIA)
- gpu::SyncToken TestSharedImageInterface::GenVerifiedSyncToken() {
- base::AutoLock locked(lock_);
- most_recent_generated_token_ =
- gpu::SyncToken(gpu::CommandBufferNamespace::GPU_IO,
- gpu::CommandBufferId(), ++release_id_);
- most_recent_generated_token_.SetVerifyFlush();
- return most_recent_generated_token_;
- }
- gpu::SyncToken TestSharedImageInterface::GenUnverifiedSyncToken() {
- base::AutoLock locked(lock_);
- most_recent_generated_token_ =
- gpu::SyncToken(gpu::CommandBufferNamespace::GPU_IO,
- gpu::CommandBufferId(), ++release_id_);
- return most_recent_generated_token_;
- }
- void TestSharedImageInterface::WaitSyncToken(const gpu::SyncToken& sync_token) {
- NOTREACHED();
- }
- void TestSharedImageInterface::Flush() {
- // No need to flush in this implementation.
- }
- scoped_refptr<gfx::NativePixmap> TestSharedImageInterface::GetNativePixmap(
- const gpu::Mailbox& mailbox) {
- return nullptr;
- }
- bool TestSharedImageInterface::CheckSharedImageExists(
- const gpu::Mailbox& mailbox) const {
- base::AutoLock locked(lock_);
- return shared_images_.contains(mailbox);
- }
- // static
- scoped_refptr<TestContextProvider> TestContextProvider::Create(
- std::string additional_extensions) {
- constexpr bool support_locking = false;
- return new TestContextProvider(
- std::make_unique<TestContextSupport>(),
- std::make_unique<TestGLES2InterfaceForContextProvider>(
- std::move(additional_extensions)),
- /*raster=*/nullptr,
- /*sii=*/nullptr, support_locking);
- }
- // static
- scoped_refptr<TestContextProvider> TestContextProvider::CreateWorker() {
- return CreateWorker(std::make_unique<TestContextSupport>());
- }
- // static
- scoped_refptr<TestContextProvider> TestContextProvider::CreateWorker(
- std::unique_ptr<TestContextSupport> support) {
- DCHECK(support);
- auto worker_context_provider = base::MakeRefCounted<TestContextProvider>(
- std::move(support), std::make_unique<TestRasterInterface>(),
- /*support_locking=*/true);
- // Worker contexts are bound to the thread they are created on.
- auto result = worker_context_provider->BindToCurrentThread();
- if (result != gpu::ContextResult::kSuccess)
- return nullptr;
- return worker_context_provider;
- }
- // static
- scoped_refptr<TestContextProvider> TestContextProvider::Create(
- std::unique_ptr<TestGLES2Interface> gl) {
- DCHECK(gl);
- constexpr bool support_locking = false;
- return new TestContextProvider(std::make_unique<TestContextSupport>(),
- std::move(gl), /*raster=*/nullptr,
- /*sii=*/nullptr, support_locking);
- }
- // static
- scoped_refptr<TestContextProvider> TestContextProvider::Create(
- std::unique_ptr<TestSharedImageInterface> sii) {
- DCHECK(sii);
- constexpr bool support_locking = false;
- return new TestContextProvider(
- std::make_unique<TestContextSupport>(),
- std::make_unique<TestGLES2InterfaceForContextProvider>(),
- /*raster=*/nullptr, std::move(sii), support_locking);
- }
- // static
- scoped_refptr<TestContextProvider> TestContextProvider::Create(
- std::unique_ptr<TestContextSupport> support) {
- DCHECK(support);
- constexpr bool support_locking = false;
- return new TestContextProvider(
- std::move(support),
- std::make_unique<TestGLES2InterfaceForContextProvider>(),
- /*raster=*/nullptr, /*sii=*/nullptr, support_locking);
- }
- TestContextProvider::TestContextProvider(
- std::unique_ptr<TestContextSupport> support,
- std::unique_ptr<TestRasterInterface> raster,
- bool support_locking)
- : support_(std::move(support)),
- raster_context_(std::move(raster)),
- shared_image_interface_(std::make_unique<TestSharedImageInterface>()),
- support_locking_(support_locking) {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- DCHECK(raster_context_);
- context_thread_checker_.DetachFromThread();
- raster_context_->set_test_support(support_.get());
- // Just pass nullptr to the ContextCacheController for its task runner.
- // Idle handling is tested directly in ContextCacheController's
- // unittests, and isn't needed here.
- cache_controller_ =
- std::make_unique<ContextCacheController>(support_.get(), nullptr);
- }
- TestContextProvider::TestContextProvider(
- std::unique_ptr<TestContextSupport> support,
- std::unique_ptr<TestGLES2Interface> gl,
- std::unique_ptr<gpu::raster::RasterInterface> raster,
- std::unique_ptr<TestSharedImageInterface> sii,
- bool support_locking)
- : support_(std::move(support)),
- context_gl_(std::move(gl)),
- raster_interface_gles_(std::move(raster)),
- shared_image_interface_(
- sii ? std::move(sii) : std::make_unique<TestSharedImageInterface>()),
- support_locking_(support_locking) {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- DCHECK(context_gl_);
- context_thread_checker_.DetachFromThread();
- context_gl_->set_test_support(support_.get());
- if (!raster_interface_gles_) {
- raster_interface_gles_ =
- std::make_unique<gpu::raster::RasterImplementationGLES>(
- context_gl_.get(), support_.get());
- }
- // Just pass nullptr to the ContextCacheController for its task runner.
- // Idle handling is tested directly in ContextCacheController's
- // unittests, and isn't needed here.
- cache_controller_ =
- std::make_unique<ContextCacheController>(support_.get(), nullptr);
- }
- TestContextProvider::~TestContextProvider() {
- DCHECK(main_thread_checker_.CalledOnValidThread() ||
- context_thread_checker_.CalledOnValidThread());
- }
- void TestContextProvider::AddRef() const {
- base::RefCountedThreadSafe<TestContextProvider>::AddRef();
- }
- void TestContextProvider::Release() const {
- base::RefCountedThreadSafe<TestContextProvider>::Release();
- }
- gpu::ContextResult TestContextProvider::BindToCurrentThread() {
- // This is called on the thread the context will be used.
- DCHECK(context_thread_checker_.CalledOnValidThread());
- if (!bound_) {
- if (context_gl_) {
- if (context_gl_->GetGraphicsResetStatusKHR() != GL_NO_ERROR)
- return gpu::ContextResult::kTransientFailure;
- context_gl_->set_context_lost_callback(base::BindOnce(
- &TestContextProvider::OnLostContext, base::Unretained(this)));
- } else {
- if (raster_context_->GetGraphicsResetStatusKHR() != GL_NO_ERROR)
- return gpu::ContextResult::kTransientFailure;
- raster_context_->set_context_lost_callback(base::BindOnce(
- &TestContextProvider::OnLostContext, base::Unretained(this)));
- }
- }
- bound_ = true;
- return gpu::ContextResult::kSuccess;
- }
- const gpu::Capabilities& TestContextProvider::ContextCapabilities() const {
- DCHECK(bound_);
- CheckValidThreadOrLockAcquired();
- if (context_gl_)
- return context_gl_->test_capabilities();
- return raster_context_->capabilities();
- }
- const gpu::GpuFeatureInfo& TestContextProvider::GetGpuFeatureInfo() const {
- DCHECK(bound_);
- CheckValidThreadOrLockAcquired();
- return gpu_feature_info_;
- }
- gpu::gles2::GLES2Interface* TestContextProvider::ContextGL() {
- DCHECK(bound_);
- CheckValidThreadOrLockAcquired();
- return context_gl_.get();
- }
- gpu::raster::RasterInterface* TestContextProvider::RasterInterface() {
- return raster_context_ ? raster_context_.get() : raster_interface_gles_.get();
- }
- gpu::ContextSupport* TestContextProvider::ContextSupport() {
- return support();
- }
- class GrDirectContext* TestContextProvider::GrContext() {
- DCHECK(bound_);
- CheckValidThreadOrLockAcquired();
- if (!context_gl_)
- return nullptr;
- if (gr_context_)
- return gr_context_->get();
- size_t max_resource_cache_bytes;
- size_t max_glyph_cache_texture_bytes;
- gpu::DefaultGrCacheLimitsForTests(&max_resource_cache_bytes,
- &max_glyph_cache_texture_bytes);
- gr_context_ = std::make_unique<skia_bindings::GrContextForGLES2Interface>(
- context_gl_.get(), support_.get(), context_gl_->test_capabilities(),
- max_resource_cache_bytes, max_glyph_cache_texture_bytes, true);
- cache_controller_->SetGrContext(gr_context_->get());
- // If GlContext is already lost, also abandon the new GrContext.
- if (ContextGL()->GetGraphicsResetStatusKHR() != GL_NO_ERROR)
- gr_context_->get()->abandonContext();
- return gr_context_->get();
- }
- TestSharedImageInterface* TestContextProvider::SharedImageInterface() {
- return shared_image_interface_.get();
- }
- ContextCacheController* TestContextProvider::CacheController() {
- CheckValidThreadOrLockAcquired();
- return cache_controller_.get();
- }
- base::Lock* TestContextProvider::GetLock() {
- if (!support_locking_)
- return nullptr;
- return &context_lock_;
- }
- void TestContextProvider::OnLostContext() {
- CheckValidThreadOrLockAcquired();
- for (auto& observer : observers_)
- observer.OnContextLost();
- if (gr_context_)
- gr_context_->get()->abandonContext();
- }
- TestGLES2Interface* TestContextProvider::TestContextGL() {
- DCHECK(bound_);
- CheckValidThreadOrLockAcquired();
- return context_gl_.get();
- }
- TestRasterInterface* TestContextProvider::GetTestRasterInterface() {
- DCHECK(bound_);
- CheckValidThreadOrLockAcquired();
- return raster_context_.get();
- }
- TestRasterInterface* TestContextProvider::UnboundTestRasterInterface() {
- return raster_context_.get();
- }
- void TestContextProvider::AddObserver(ContextLostObserver* obs) {
- observers_.AddObserver(obs);
- }
- void TestContextProvider::RemoveObserver(ContextLostObserver* obs) {
- observers_.RemoveObserver(obs);
- }
- } // namespace viz
|