7#include "gmock/gmock.h"
8#include "gtest/gtest.h"
28using ::testing::ElementsAreArray;
29using ::testing::NiceMock;
30using ::testing::Return;
31using ::testing::SetArgPointee;
32using ::testing::TestWithParam;
34class TestReactorGLES :
public ReactorGLES {
59 :
public TestWithParam<DiscardFrameBufferParams> {};
62std::shared_ptr<ContextGLES> CreateFakeGLESContext(
64 auto dummy_gl_procs = std::make_unique<ProcTableGLES>(std::move(resolver));
65 auto dummy_shader_library = std::vector<std::shared_ptr<fml::Mapping>>{};
68 dummy_shader_library,
false);
71struct RenderPassGLESContext {
84 auto mock_gl_impl = std::make_unique<NiceMock<MockGLESImpl>>();
87 MockGLES::Init(std::move(mock_gl_impl), {{
"GL_EXT_discard_framebuffer"}},
90 auto context = CreateFakeGLESContext();
96 std::static_pointer_cast<Context>(
context)->CreateCommandBuffer();
101 const auto& test_params = GetParam();
102 auto framebuffer_texture =
107 render_target.SetColorAttachment(color_attachment, 0);
111 .WillOnce(SetArgPointee<1>(test_params.frame_buffer_id));
114 .With(Args<2, 1>(ElementsAreArray(test_params.expected_attachments)))
123 ::testing::ValuesIn(std::vector<DiscardFrameBufferParams>{
124 {.frame_buffer_id = 0,
125 .expected_attachments = {GL_COLOR_EXT, GL_DEPTH_EXT, GL_STENCIL_EXT}},
126 {.frame_buffer_id = 1,
127 .expected_attachments = {GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT,
128 GL_STENCIL_ATTACHMENT}}}),
129 [](const ::testing::TestParamInfo<DiscardFrameBufferParams>& info) {
130 return (info.param.frame_buffer_id == 0) ?
"Default" :
"NonDefault";
134 auto mock_gl_impl = std::make_unique<NiceMock<MockGLESImpl>>();
137 MockGLES::Init(std::move(mock_gl_impl), std::nullopt,
"OpenGL ES 3.0");
139 auto context = CreateFakeGLESContext();
145 std::static_pointer_cast<Context>(
context)->CreateCommandBuffer();
150 const auto& test_params = GetParam();
151 auto framebuffer_texture =
156 render_target.SetColorAttachment(color_attachment, 0);
160 .WillOnce(SetArgPointee<1>(test_params.frame_buffer_id));
164 .With(Args<2, 1>(ElementsAreArray(test_params.expected_attachments)))
173TEST(RenderPassGLESTest, ResolvingMultisampleTextureCachesResolveFBO) {
174 auto mock_gl_impl = std::make_unique<NiceMock<MockGLESImpl>>();
178 MockGLES::Init(std::move(mock_gl_impl), std::nullopt,
"OpenGL ES 3.0");
180 auto context = CreateFakeGLESContext();
186 std::static_pointer_cast<Context>(
context)->CreateCommandBuffer();
188 const auto msaa_desc =
194 const auto resolve_desc =
202 auto msaa_tex = std::make_shared<TextureGLES>(
reactor, msaa_desc);
203 auto resolve_tex = std::make_shared<TextureGLES>(
reactor, resolve_desc);
208 .resolve_texture = resolve_tex,
213 render_target.SetColorAttachment(color_attachment, 0);
216 .WillRepeatedly(Return(GL_FRAMEBUFFER_COMPLETE));
228 const auto render_pass2 =
command_buffer->CreateRenderPass(render_target);
229 ASSERT_TRUE(render_pass2->EncodeCommands());
242 std::unique_ptr<NiceMock<MockGLESImpl>> mock_gl_impl =
243 std::make_unique<NiceMock<MockGLESImpl>>();
247 std::shared_ptr<ContextGLES>
context =
248 CreateFakeGLESContext(std::move(resolver));
249 std::shared_ptr<MockWorker>
dummy_worker = std::make_shared<MockWorker>();
254 tex_desc.
size = {100, 100};
256 auto texture = std::make_shared<TextureGLES>(
reactor, tex_desc,
false);
263 target.SetColorAttachment(color0, 0);
266 std::static_pointer_cast<Context>(
context)->CreateCommandBuffer();
271 .WillRepeatedly(Return(GL_FRAMEBUFFER_COMPLETE));
279 std::shared_ptr<PipelineGLES>
pipeline =
281 reactor, std::weak_ptr<PipelineLibrary>(), desc,
282 std::make_shared<UniqueHandleGLES>(
reactor, pipeline_handle)));
283 pipeline->buffer_bindings_ = std::make_unique<BufferBindingsGLES>();
293 auto ctx = CreateRenderPassGLESContext();
295 std::shared_ptr<RenderPass>&
render_pass = ctx.render_pass;
296 std::shared_ptr<PipelineGLES>&
pipeline = ctx.pipeline;
297 std::shared_ptr<ReactorGLES>&
reactor = ctx.reactor;
329 CommandsWithoutViewportGetRenderPassViewport) {
330 auto ctx = CreateRenderPassGLESContext();
332 std::shared_ptr<RenderPass>&
render_pass = ctx.render_pass;
333 std::shared_ptr<PipelineGLES>&
pipeline = ctx.pipeline;
334 std::shared_ptr<ReactorGLES>&
reactor = ctx.reactor;
365 auto ctx = CreateRenderPassGLESContext();
367 std::shared_ptr<RenderPass>&
render_pass = ctx.render_pass;
368 std::shared_ptr<PipelineGLES>&
pipeline = ctx.pipeline;
369 std::shared_ptr<ReactorGLES>&
reactor = ctx.reactor;
389 auto ctx = CreateRenderPassGLESContext();
391 std::shared_ptr<RenderPass>&
render_pass = ctx.render_pass;
392 std::shared_ptr<PipelineGLES>&
pipeline = ctx.pipeline;
393 std::shared_ptr<ReactorGLES>&
reactor = ctx.reactor;
402 DrawArraysInstanced(_, 0, 3,
414 auto ctx = CreateRenderPassGLESContext();
416 std::shared_ptr<RenderPass>&
render_pass = ctx.render_pass;
417 std::shared_ptr<PipelineGLES>&
pipeline = ctx.pipeline;
418 std::shared_ptr<ReactorGLES>&
reactor = ctx.reactor;
421 index_desc.
size = 6 *
sizeof(uint16_t);
423 auto index_buffer = std::static_pointer_cast<Context>(ctx.context)
424 ->GetResourceAllocator()
425 ->CreateBuffer(index_desc);
426 ASSERT_TRUE(index_buffer);
436 DrawElementsInstanced(_, 6, _,
451 std::shared_ptr<RenderPass>&
render_pass = ctx.render_pass;
452 std::shared_ptr<PipelineGLES>&
pipeline = ctx.pipeline;
453 std::shared_ptr<ReactorGLES>&
reactor = ctx.reactor;
475 std::shared_ptr<RenderPass>&
render_pass = ctx.render_pass;
476 std::shared_ptr<PipelineGLES>&
pipeline = ctx.pipeline;
477 std::shared_ptr<ReactorGLES>&
reactor = ctx.reactor;
480 index_desc.
size = 6 *
sizeof(uint16_t);
482 auto index_buffer = std::static_pointer_cast<Context>(ctx.context)
483 ->GetResourceAllocator()
484 ->CreateBuffer(index_desc);
485 ASSERT_TRUE(index_buffer);
495 DrawElements(_, 6, _, _))
497 EXPECT_CALL(
mock_gl_impl_ref, DrawElementsInstanced(_, _, _, _, _)).Times(0);
506 auto ctx = CreateRenderPassGLESContext();
508 std::shared_ptr<RenderPass>&
render_pass = ctx.render_pass;
509 std::shared_ptr<PipelineGLES>&
pipeline = ctx.pipeline;
510 std::shared_ptr<ReactorGLES>&
reactor = ctx.reactor;
529 auto ctx = CreateRenderPassGLESContext();
531 std::shared_ptr<RenderPass>&
render_pass = ctx.render_pass;
532 std::shared_ptr<PipelineGLES>&
pipeline = ctx.pipeline;
533 std::shared_ptr<ReactorGLES>&
reactor = ctx.reactor;
static std::shared_ptr< ContextGLES > Create(const Flags &flags, std::unique_ptr< ProcTableGLES > gl, const std::vector< std::shared_ptr< fml::Mapping > > &shader_libraries, bool enable_gpu_tracing)
static BufferView AsBufferView(std::shared_ptr< DeviceBuffer > buffer)
Create a buffer view of this entire buffer.
Represents a handle to an underlying OpenGL object. Unlike OpenGL object handles, these handles can b...
PipelineDescriptor & SetColorAttachmentDescriptor(size_t index, ColorAttachmentDescriptor desc)
std::function< void *(const char *function_name)> Resolver
A delegate implemented by a thread on which an OpenGL context is current. There may be multiple worke...
The reactor attempts to make thread-safe usage of OpenGL ES easier to reason about.
static std::shared_ptr< TextureGLES > WrapFBO(std::shared_ptr< ReactorGLES > reactor, TextureDescriptor desc, GLuint fbo)
Create a texture by wrapping an external framebuffer object whose lifecycle is owned by the caller.
static std::shared_ptr< MockGLES > Init(std::unique_ptr< MockGLESImpl > impl, const std::optional< std::vector< const char * > > &extensions=std::nullopt, const char *version_string="OpenGL ES 3.0")
bool CanReactorReactOnCurrentThreadNow(const ReactorGLES &reactor) const override
Determines the ability of the worker to service a reaction on the current thread. The OpenGL context ...
static RenderPassGLESContext CreateRenderPassGLESContext(ProcTableGLES::Resolver resolver=kMockResolverGLES)
~TestReactorGLES()=default
TEST(FrameTimingsRecorderTest, RecordVsync)
const ProcTableGLES::Resolver kMockResolverGLESWithoutInstancing
TEST_P(AiksTest, DrawAtlasNoColor)
const ProcTableGLES::Resolver kMockResolverGLES
TEST_F(GoldenTests, ConicalGradient)
INSTANTIATE_TEST_SUITE_P(FrameBufferObject, RenderPassGLESWithDiscardFrameBufferExtTest, ::testing::ValuesIn(std::vector< DiscardFrameBufferParams >{ {.frame_buffer_id=0,.expected_attachments={GL_COLOR_EXT, GL_DEPTH_EXT, GL_STENCIL_EXT}}, {.frame_buffer_id=1,.expected_attachments={GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT}}}), [](const ::testing::TestParamInfo< DiscardFrameBufferParams > &info) { return(info.param.frame_buffer_id==0) ? "Default" :"NonDefault";})
@ kNone
Does not use the index buffer.
raw_ptr< Pipeline< PipelineDescriptor > > PipelineRef
A raw ptr to a pipeline object.
std::shared_ptr< MockWorker > dummy_worker
std::shared_ptr< ReactorGLES > reactor
std::shared_ptr< ContextGLES > context
std::shared_ptr< RenderPass > render_pass
testing::NiceMock< MockGLESImpl > & mock_gl_impl_ref
std::shared_ptr< PipelineGLES > pipeline
std::shared_ptr< MockGLES > mock_gl
std::shared_ptr< CommandBuffer > command_buffer
std::shared_ptr< Texture > texture
Describe the color attachment that will be used with this pipeline.
static constexpr Color Black()
static constexpr TRect MakeXYWH(Type x, Type y, Type width, Type height)
A lightweight object that describes the attributes of a texture that can then used an allocator to cr...
std::array< GLenum, 3 > expected_attachments