test_context_provider.cc 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536
  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. #include "components/viz/test/test_context_provider.h"
  5. #include <stddef.h>
  6. #include <stdint.h>
  7. #include <limits>
  8. #include <memory>
  9. #include <set>
  10. #include <utility>
  11. #include <vector>
  12. #include "base/bind.h"
  13. #include "base/callback_helpers.h"
  14. #include "base/check.h"
  15. #include "base/notreached.h"
  16. #include "build/build_config.h"
  17. #include "components/viz/common/gpu/context_cache_controller.h"
  18. #include "components/viz/test/test_gles2_interface.h"
  19. #include "components/viz/test/test_raster_interface.h"
  20. #include "gpu/command_buffer/client/raster_implementation_gles.h"
  21. #include "gpu/config/skia_limits.h"
  22. #include "gpu/skia_bindings/grcontext_for_gles2_interface.h"
  23. #include "third_party/skia/include/gpu/GrDirectContext.h"
  24. #include "third_party/skia/include/gpu/gl/GrGLInterface.h"
  25. #include "ui/gfx/gpu_fence.h"
  26. #include "ui/gfx/gpu_memory_buffer.h"
  27. namespace viz {
  28. namespace {
  29. // Various tests rely on functionality (capabilities) enabled by these extension
  30. // strings.
  31. const char* const kExtensions[] = {"GL_EXT_stencil_wrap",
  32. "GL_EXT_texture_format_BGRA8888",
  33. "GL_OES_rgb8_rgba8",
  34. "GL_EXT_texture_norm16",
  35. "GL_CHROMIUM_framebuffer_multisample",
  36. "GL_CHROMIUM_renderbuffer_format_BGRA8888",
  37. "GL_OES_texture_half_float",
  38. "GL_OES_texture_half_float_linear",
  39. "GL_EXT_color_buffer_half_float"};
  40. class TestGLES2InterfaceForContextProvider : public TestGLES2Interface {
  41. public:
  42. TestGLES2InterfaceForContextProvider(
  43. std::string additional_extensions = std::string())
  44. : extension_string_(
  45. BuildExtensionString(std::move(additional_extensions))) {}
  46. TestGLES2InterfaceForContextProvider(
  47. const TestGLES2InterfaceForContextProvider&) = delete;
  48. TestGLES2InterfaceForContextProvider& operator=(
  49. const TestGLES2InterfaceForContextProvider&) = delete;
  50. ~TestGLES2InterfaceForContextProvider() override = default;
  51. // TestGLES2Interface:
  52. const GLubyte* GetString(GLenum name) override {
  53. switch (name) {
  54. case GL_EXTENSIONS:
  55. return reinterpret_cast<const GLubyte*>(extension_string_.c_str());
  56. case GL_VERSION:
  57. return reinterpret_cast<const GrGLubyte*>("4.0 Null GL");
  58. case GL_SHADING_LANGUAGE_VERSION:
  59. return reinterpret_cast<const GrGLubyte*>("4.20.8 Null GLSL");
  60. case GL_VENDOR:
  61. return reinterpret_cast<const GrGLubyte*>("Null Vendor");
  62. case GL_RENDERER:
  63. return reinterpret_cast<const GrGLubyte*>("The Null (Non-)Renderer");
  64. }
  65. return nullptr;
  66. }
  67. const GrGLubyte* GetStringi(GrGLenum name, GrGLuint i) override {
  68. if (name == GL_EXTENSIONS && i < std::size(kExtensions))
  69. return reinterpret_cast<const GLubyte*>(kExtensions[i]);
  70. return nullptr;
  71. }
  72. void GetIntegerv(GLenum name, GLint* params) override {
  73. switch (name) {
  74. case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
  75. *params = 8;
  76. return;
  77. case GL_MAX_RENDERBUFFER_SIZE:
  78. *params = 2048;
  79. break;
  80. case GL_MAX_TEXTURE_SIZE:
  81. *params = 2048;
  82. break;
  83. case GL_MAX_TEXTURE_IMAGE_UNITS:
  84. *params = 8;
  85. break;
  86. case GL_MAX_VERTEX_ATTRIBS:
  87. *params = 8;
  88. break;
  89. case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
  90. *params = 0;
  91. return;
  92. default:
  93. break;
  94. }
  95. TestGLES2Interface::GetIntegerv(name, params);
  96. }
  97. private:
  98. static std::string BuildExtensionString(std::string additional_extensions) {
  99. std::string extension_string = kExtensions[0];
  100. for (size_t i = 1; i < std::size(kExtensions); ++i) {
  101. extension_string += " ";
  102. extension_string += kExtensions[i];
  103. }
  104. if (!additional_extensions.empty()) {
  105. extension_string += " ";
  106. extension_string += additional_extensions;
  107. }
  108. return extension_string;
  109. }
  110. const std::string extension_string_;
  111. };
  112. } // namespace
  113. TestSharedImageInterface::TestSharedImageInterface() = default;
  114. TestSharedImageInterface::~TestSharedImageInterface() = default;
  115. gpu::Mailbox TestSharedImageInterface::CreateSharedImage(
  116. ResourceFormat format,
  117. const gfx::Size& size,
  118. const gfx::ColorSpace& color_space,
  119. GrSurfaceOrigin surface_origin,
  120. SkAlphaType alpha_type,
  121. uint32_t usage,
  122. gpu::SurfaceHandle surface_handle) {
  123. base::AutoLock locked(lock_);
  124. auto mailbox = gpu::Mailbox::GenerateForSharedImage();
  125. shared_images_.insert(mailbox);
  126. most_recent_size_ = size;
  127. return mailbox;
  128. }
  129. gpu::Mailbox TestSharedImageInterface::CreateSharedImage(
  130. ResourceFormat format,
  131. const gfx::Size& size,
  132. const gfx::ColorSpace& color_space,
  133. GrSurfaceOrigin surface_origin,
  134. SkAlphaType alpha_type,
  135. uint32_t usage,
  136. base::span<const uint8_t> pixel_data) {
  137. base::AutoLock locked(lock_);
  138. auto mailbox = gpu::Mailbox::GenerateForSharedImage();
  139. shared_images_.insert(mailbox);
  140. return mailbox;
  141. }
  142. gpu::Mailbox TestSharedImageInterface::CreateSharedImage(
  143. gfx::GpuMemoryBuffer* gpu_memory_buffer,
  144. gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
  145. gfx::BufferPlane plane,
  146. const gfx::ColorSpace& color_space,
  147. GrSurfaceOrigin surface_origin,
  148. SkAlphaType alpha_type,
  149. uint32_t usage) {
  150. base::AutoLock locked(lock_);
  151. auto mailbox = gpu::Mailbox::GenerateForSharedImage();
  152. shared_images_.insert(mailbox);
  153. most_recent_size_ = gpu_memory_buffer->GetSize();
  154. return mailbox;
  155. }
  156. std::vector<gpu::Mailbox>
  157. TestSharedImageInterface::CreateSharedImageVideoPlanes(
  158. gfx::GpuMemoryBuffer* gpu_memory_buffer,
  159. gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
  160. uint32_t usage) {
  161. base::AutoLock locked(lock_);
  162. auto mailboxes =
  163. std::vector<gpu::Mailbox>{gpu::Mailbox::GenerateForSharedImage(),
  164. gpu::Mailbox::GenerateForSharedImage()};
  165. shared_images_.insert(mailboxes[0]);
  166. shared_images_.insert(mailboxes[1]);
  167. most_recent_size_ = gpu_memory_buffer->GetSize();
  168. return mailboxes;
  169. }
  170. void TestSharedImageInterface::UpdateSharedImage(
  171. const gpu::SyncToken& sync_token,
  172. const gpu::Mailbox& mailbox) {
  173. base::AutoLock locked(lock_);
  174. DCHECK(shared_images_.find(mailbox) != shared_images_.end());
  175. }
  176. void TestSharedImageInterface::UpdateSharedImage(
  177. const gpu::SyncToken& sync_token,
  178. std::unique_ptr<gfx::GpuFence> acquire_fence,
  179. const gpu::Mailbox& mailbox) {
  180. base::AutoLock locked(lock_);
  181. DCHECK(shared_images_.find(mailbox) != shared_images_.end());
  182. }
  183. void TestSharedImageInterface::DestroySharedImage(
  184. const gpu::SyncToken& sync_token,
  185. const gpu::Mailbox& mailbox) {
  186. base::AutoLock locked(lock_);
  187. shared_images_.erase(mailbox);
  188. most_recent_destroy_token_ = sync_token;
  189. }
  190. gpu::SharedImageInterface::SwapChainMailboxes
  191. TestSharedImageInterface::CreateSwapChain(ResourceFormat format,
  192. const gfx::Size& size,
  193. const gfx::ColorSpace& color_space,
  194. GrSurfaceOrigin surface_origin,
  195. SkAlphaType alpha_type,
  196. uint32_t usage) {
  197. auto front_buffer = gpu::Mailbox::GenerateForSharedImage();
  198. auto back_buffer = gpu::Mailbox::GenerateForSharedImage();
  199. shared_images_.insert(front_buffer);
  200. shared_images_.insert(back_buffer);
  201. return {front_buffer, back_buffer};
  202. }
  203. void TestSharedImageInterface::PresentSwapChain(
  204. const gpu::SyncToken& sync_token,
  205. const gpu::Mailbox& mailbox) {}
  206. #if BUILDFLAG(IS_FUCHSIA)
  207. void TestSharedImageInterface::RegisterSysmemBufferCollection(
  208. gfx::SysmemBufferCollectionId id,
  209. zx::channel token,
  210. gfx::BufferFormat format,
  211. gfx::BufferUsage usage,
  212. bool register_with_image_pipe) {
  213. NOTREACHED();
  214. }
  215. void TestSharedImageInterface::ReleaseSysmemBufferCollection(
  216. gfx::SysmemBufferCollectionId id) {
  217. NOTREACHED();
  218. }
  219. #endif // BUILDFLAG(IS_FUCHSIA)
  220. gpu::SyncToken TestSharedImageInterface::GenVerifiedSyncToken() {
  221. base::AutoLock locked(lock_);
  222. most_recent_generated_token_ =
  223. gpu::SyncToken(gpu::CommandBufferNamespace::GPU_IO,
  224. gpu::CommandBufferId(), ++release_id_);
  225. most_recent_generated_token_.SetVerifyFlush();
  226. return most_recent_generated_token_;
  227. }
  228. gpu::SyncToken TestSharedImageInterface::GenUnverifiedSyncToken() {
  229. base::AutoLock locked(lock_);
  230. most_recent_generated_token_ =
  231. gpu::SyncToken(gpu::CommandBufferNamespace::GPU_IO,
  232. gpu::CommandBufferId(), ++release_id_);
  233. return most_recent_generated_token_;
  234. }
  235. void TestSharedImageInterface::WaitSyncToken(const gpu::SyncToken& sync_token) {
  236. NOTREACHED();
  237. }
  238. void TestSharedImageInterface::Flush() {
  239. // No need to flush in this implementation.
  240. }
  241. scoped_refptr<gfx::NativePixmap> TestSharedImageInterface::GetNativePixmap(
  242. const gpu::Mailbox& mailbox) {
  243. return nullptr;
  244. }
  245. bool TestSharedImageInterface::CheckSharedImageExists(
  246. const gpu::Mailbox& mailbox) const {
  247. base::AutoLock locked(lock_);
  248. return shared_images_.contains(mailbox);
  249. }
  250. // static
  251. scoped_refptr<TestContextProvider> TestContextProvider::Create(
  252. std::string additional_extensions) {
  253. constexpr bool support_locking = false;
  254. return new TestContextProvider(
  255. std::make_unique<TestContextSupport>(),
  256. std::make_unique<TestGLES2InterfaceForContextProvider>(
  257. std::move(additional_extensions)),
  258. /*raster=*/nullptr,
  259. /*sii=*/nullptr, support_locking);
  260. }
  261. // static
  262. scoped_refptr<TestContextProvider> TestContextProvider::CreateWorker() {
  263. return CreateWorker(std::make_unique<TestContextSupport>());
  264. }
  265. // static
  266. scoped_refptr<TestContextProvider> TestContextProvider::CreateWorker(
  267. std::unique_ptr<TestContextSupport> support) {
  268. DCHECK(support);
  269. auto worker_context_provider = base::MakeRefCounted<TestContextProvider>(
  270. std::move(support), std::make_unique<TestRasterInterface>(),
  271. /*support_locking=*/true);
  272. // Worker contexts are bound to the thread they are created on.
  273. auto result = worker_context_provider->BindToCurrentThread();
  274. if (result != gpu::ContextResult::kSuccess)
  275. return nullptr;
  276. return worker_context_provider;
  277. }
  278. // static
  279. scoped_refptr<TestContextProvider> TestContextProvider::Create(
  280. std::unique_ptr<TestGLES2Interface> gl) {
  281. DCHECK(gl);
  282. constexpr bool support_locking = false;
  283. return new TestContextProvider(std::make_unique<TestContextSupport>(),
  284. std::move(gl), /*raster=*/nullptr,
  285. /*sii=*/nullptr, support_locking);
  286. }
  287. // static
  288. scoped_refptr<TestContextProvider> TestContextProvider::Create(
  289. std::unique_ptr<TestSharedImageInterface> sii) {
  290. DCHECK(sii);
  291. constexpr bool support_locking = false;
  292. return new TestContextProvider(
  293. std::make_unique<TestContextSupport>(),
  294. std::make_unique<TestGLES2InterfaceForContextProvider>(),
  295. /*raster=*/nullptr, std::move(sii), support_locking);
  296. }
  297. // static
  298. scoped_refptr<TestContextProvider> TestContextProvider::Create(
  299. std::unique_ptr<TestContextSupport> support) {
  300. DCHECK(support);
  301. constexpr bool support_locking = false;
  302. return new TestContextProvider(
  303. std::move(support),
  304. std::make_unique<TestGLES2InterfaceForContextProvider>(),
  305. /*raster=*/nullptr, /*sii=*/nullptr, support_locking);
  306. }
  307. TestContextProvider::TestContextProvider(
  308. std::unique_ptr<TestContextSupport> support,
  309. std::unique_ptr<TestRasterInterface> raster,
  310. bool support_locking)
  311. : support_(std::move(support)),
  312. raster_context_(std::move(raster)),
  313. shared_image_interface_(std::make_unique<TestSharedImageInterface>()),
  314. support_locking_(support_locking) {
  315. DCHECK(main_thread_checker_.CalledOnValidThread());
  316. DCHECK(raster_context_);
  317. context_thread_checker_.DetachFromThread();
  318. raster_context_->set_test_support(support_.get());
  319. // Just pass nullptr to the ContextCacheController for its task runner.
  320. // Idle handling is tested directly in ContextCacheController's
  321. // unittests, and isn't needed here.
  322. cache_controller_ =
  323. std::make_unique<ContextCacheController>(support_.get(), nullptr);
  324. }
  325. TestContextProvider::TestContextProvider(
  326. std::unique_ptr<TestContextSupport> support,
  327. std::unique_ptr<TestGLES2Interface> gl,
  328. std::unique_ptr<gpu::raster::RasterInterface> raster,
  329. std::unique_ptr<TestSharedImageInterface> sii,
  330. bool support_locking)
  331. : support_(std::move(support)),
  332. context_gl_(std::move(gl)),
  333. raster_interface_gles_(std::move(raster)),
  334. shared_image_interface_(
  335. sii ? std::move(sii) : std::make_unique<TestSharedImageInterface>()),
  336. support_locking_(support_locking) {
  337. DCHECK(main_thread_checker_.CalledOnValidThread());
  338. DCHECK(context_gl_);
  339. context_thread_checker_.DetachFromThread();
  340. context_gl_->set_test_support(support_.get());
  341. if (!raster_interface_gles_) {
  342. raster_interface_gles_ =
  343. std::make_unique<gpu::raster::RasterImplementationGLES>(
  344. context_gl_.get(), support_.get());
  345. }
  346. // Just pass nullptr to the ContextCacheController for its task runner.
  347. // Idle handling is tested directly in ContextCacheController's
  348. // unittests, and isn't needed here.
  349. cache_controller_ =
  350. std::make_unique<ContextCacheController>(support_.get(), nullptr);
  351. }
  352. TestContextProvider::~TestContextProvider() {
  353. DCHECK(main_thread_checker_.CalledOnValidThread() ||
  354. context_thread_checker_.CalledOnValidThread());
  355. }
  356. void TestContextProvider::AddRef() const {
  357. base::RefCountedThreadSafe<TestContextProvider>::AddRef();
  358. }
  359. void TestContextProvider::Release() const {
  360. base::RefCountedThreadSafe<TestContextProvider>::Release();
  361. }
  362. gpu::ContextResult TestContextProvider::BindToCurrentThread() {
  363. // This is called on the thread the context will be used.
  364. DCHECK(context_thread_checker_.CalledOnValidThread());
  365. if (!bound_) {
  366. if (context_gl_) {
  367. if (context_gl_->GetGraphicsResetStatusKHR() != GL_NO_ERROR)
  368. return gpu::ContextResult::kTransientFailure;
  369. context_gl_->set_context_lost_callback(base::BindOnce(
  370. &TestContextProvider::OnLostContext, base::Unretained(this)));
  371. } else {
  372. if (raster_context_->GetGraphicsResetStatusKHR() != GL_NO_ERROR)
  373. return gpu::ContextResult::kTransientFailure;
  374. raster_context_->set_context_lost_callback(base::BindOnce(
  375. &TestContextProvider::OnLostContext, base::Unretained(this)));
  376. }
  377. }
  378. bound_ = true;
  379. return gpu::ContextResult::kSuccess;
  380. }
  381. const gpu::Capabilities& TestContextProvider::ContextCapabilities() const {
  382. DCHECK(bound_);
  383. CheckValidThreadOrLockAcquired();
  384. if (context_gl_)
  385. return context_gl_->test_capabilities();
  386. return raster_context_->capabilities();
  387. }
  388. const gpu::GpuFeatureInfo& TestContextProvider::GetGpuFeatureInfo() const {
  389. DCHECK(bound_);
  390. CheckValidThreadOrLockAcquired();
  391. return gpu_feature_info_;
  392. }
  393. gpu::gles2::GLES2Interface* TestContextProvider::ContextGL() {
  394. DCHECK(bound_);
  395. CheckValidThreadOrLockAcquired();
  396. return context_gl_.get();
  397. }
  398. gpu::raster::RasterInterface* TestContextProvider::RasterInterface() {
  399. return raster_context_ ? raster_context_.get() : raster_interface_gles_.get();
  400. }
  401. gpu::ContextSupport* TestContextProvider::ContextSupport() {
  402. return support();
  403. }
  404. class GrDirectContext* TestContextProvider::GrContext() {
  405. DCHECK(bound_);
  406. CheckValidThreadOrLockAcquired();
  407. if (!context_gl_)
  408. return nullptr;
  409. if (gr_context_)
  410. return gr_context_->get();
  411. size_t max_resource_cache_bytes;
  412. size_t max_glyph_cache_texture_bytes;
  413. gpu::DefaultGrCacheLimitsForTests(&max_resource_cache_bytes,
  414. &max_glyph_cache_texture_bytes);
  415. gr_context_ = std::make_unique<skia_bindings::GrContextForGLES2Interface>(
  416. context_gl_.get(), support_.get(), context_gl_->test_capabilities(),
  417. max_resource_cache_bytes, max_glyph_cache_texture_bytes, true);
  418. cache_controller_->SetGrContext(gr_context_->get());
  419. // If GlContext is already lost, also abandon the new GrContext.
  420. if (ContextGL()->GetGraphicsResetStatusKHR() != GL_NO_ERROR)
  421. gr_context_->get()->abandonContext();
  422. return gr_context_->get();
  423. }
  424. TestSharedImageInterface* TestContextProvider::SharedImageInterface() {
  425. return shared_image_interface_.get();
  426. }
  427. ContextCacheController* TestContextProvider::CacheController() {
  428. CheckValidThreadOrLockAcquired();
  429. return cache_controller_.get();
  430. }
  431. base::Lock* TestContextProvider::GetLock() {
  432. if (!support_locking_)
  433. return nullptr;
  434. return &context_lock_;
  435. }
  436. void TestContextProvider::OnLostContext() {
  437. CheckValidThreadOrLockAcquired();
  438. for (auto& observer : observers_)
  439. observer.OnContextLost();
  440. if (gr_context_)
  441. gr_context_->get()->abandonContext();
  442. }
  443. TestGLES2Interface* TestContextProvider::TestContextGL() {
  444. DCHECK(bound_);
  445. CheckValidThreadOrLockAcquired();
  446. return context_gl_.get();
  447. }
  448. TestRasterInterface* TestContextProvider::GetTestRasterInterface() {
  449. DCHECK(bound_);
  450. CheckValidThreadOrLockAcquired();
  451. return raster_context_.get();
  452. }
  453. TestRasterInterface* TestContextProvider::UnboundTestRasterInterface() {
  454. return raster_context_.get();
  455. }
  456. void TestContextProvider::AddObserver(ContextLostObserver* obs) {
  457. observers_.AddObserver(obs);
  458. }
  459. void TestContextProvider::RemoveObserver(ContextLostObserver* obs) {
  460. observers_.RemoveObserver(obs);
  461. }
  462. } // namespace viz