227 const std::vector<Command>& commands,
228 const std::vector<BufferView>& vertex_buffers,
229 const std::vector<TextureAndSampler>& bound_textures,
230 const std::vector<BufferResource>& bound_buffers,
231 const std::shared_ptr<GPUTracerGLES>& tracer,
232 const std::shared_ptr<const Context>& impeller_context) {
233 TRACE_EVENT0(
"impeller",
"RenderPassGLES::EncodeCommandsInReactor");
237 tracer->MarkFrameStart(gl);
240 [&gl]() { gl.PopDebugGroup(); });
241 if (!pass_data.
label.empty()) {
242 gl.PushDebugGroup(pass_data.
label);
244 pop_pass_debug_marker.
Release();
249 const bool is_wrapped_fbo = color_gles.
IsWrapped();
251 std::optional<GLuint> fbo = 0;
252 if (is_wrapped_fbo) {
253 if (color_gles.
GetFBO().has_value()) {
255 gl.BindFramebuffer(GL_FRAMEBUFFER, *color_gles.
GetFBO());
261 if (!fbo.has_value()) {
264 gl.BindFramebuffer(GL_FRAMEBUFFER, fbo.value());
270 if (!fbo.has_value()) {
273 gl.BindFramebuffer(GL_FRAMEBUFFER, fbo.value());
276 GL_FRAMEBUFFER, TextureGLES::AttachmentType::kColor0)) {
281 if (!depth->SetAsFramebufferAttachment(
282 GL_FRAMEBUFFER, TextureGLES::AttachmentType::kDepth)) {
288 if (!stencil->SetAsFramebufferAttachment(
289 GL_FRAMEBUFFER, TextureGLES::AttachmentType::kStencil)) {
294 auto status = gl.CheckFramebufferStatusDebug(GL_FRAMEBUFFER);
295 if (status != GL_FRAMEBUFFER_COMPLETE) {
309 if (gl.DepthRangef.IsAvailable()) {
319 GLenum clear_bits = 0u;
321 clear_bits |= GL_COLOR_BUFFER_BIT;
324 clear_bits |= GL_DEPTH_BUFFER_BIT;
327 clear_bits |= GL_STENCIL_BUFFER_BIT;
330 RenderPassGLES::ResetGLState(gl);
332 gl.Clear(clear_bits);
339 std::optional<Viewport> current_viewport;
340 CullMode current_cull_mode = CullMode::kNone;
341 WindingOrder current_winding_order = WindingOrder::kClockwise;
344 for (
const auto& command : commands) {
347 [&gl]() { gl.PopDebugGroup(); });
348 if (!command.label.empty()) {
349 gl.PushDebugGroup(command.label);
351 pop_cmd_debug_marker.
Release();
354 const auto& pipeline = PipelineGLES::Cast(*command.pipeline);
355 impeller_context->GetPipelineLibrary()->LogPipelineUsage(
356 pipeline.GetDescriptor());
357 const auto* color_attachment =
358 pipeline.GetDescriptor().GetLegacyCompatibleColorAttachment();
359 if (!color_attachment) {
361 <<
"Color attachment is too complicated for a legacy renderer.";
379 pipeline.GetDescriptor().GetDepthStencilAttachmentDescriptor();
381 gl.Enable(GL_DEPTH_TEST);
383 gl.DepthMask(depth->depth_write_enabled ? GL_TRUE : GL_FALSE);
385 gl.Disable(GL_DEPTH_TEST);
401 if (command.scissor.has_value()) {
402 const auto& scissor = command.scissor.value();
403 gl.Enable(GL_SCISSOR_TEST);
406 target_size.
height - scissor.GetY() - scissor.GetHeight(),
415 CullMode pipeline_cull_mode = pipeline.GetDescriptor().GetCullMode();
416 if (current_cull_mode != pipeline_cull_mode) {
417 switch (pipeline_cull_mode) {
418 case CullMode::kNone:
419 gl.Disable(GL_CULL_FACE);
421 case CullMode::kFrontFace:
422 gl.Enable(GL_CULL_FACE);
423 gl.CullFace(GL_FRONT);
425 case CullMode::kBackFace:
426 gl.Enable(GL_CULL_FACE);
427 gl.CullFace(GL_BACK);
430 current_cull_mode = pipeline_cull_mode;
437 pipeline.GetDescriptor().GetWindingOrder();
438 if (current_winding_order != pipeline_winding_order) {
439 switch (pipeline.GetDescriptor().GetWindingOrder()) {
440 case WindingOrder::kClockwise:
443 case WindingOrder::kCounterClockwise:
444 gl.FrontFace(GL_CCW);
447 current_winding_order = pipeline_winding_order;
459 for (
size_t i = 0;
i < command.vertex_buffers.length;
i++) {
461 vertex_buffers[
i + command.vertex_buffers.offset],
470 if (!pipeline.BindProgram()) {
481 command.bound_textures,
482 command.bound_buffers
496 pipeline.GetDescriptor().GetPolygonMode() == PolygonMode::kLine
498 :
ToMode(pipeline.GetDescriptor().GetPrimitiveType());
503 if (command.index_type == IndexType::kNone) {
504 gl.DrawArrays(mode, command.base_vertex, command.element_count);
507 auto index_buffer_view = command.index_buffer;
508 const DeviceBuffer* index_buffer = index_buffer_view.GetBuffer();
509 const auto& index_buffer_gles = DeviceBufferGLES::Cast(*index_buffer);
510 if (!index_buffer_gles.BindAndUploadDataIfNecessary(
511 DeviceBufferGLES::BindingType::kElementArrayBuffer)) {
514 gl.DrawElements(mode,
515 command.element_count,
517 reinterpret_cast<const GLvoid*
>(
static_cast<GLsizei
>(
518 index_buffer_view.GetRange().offset))
531 !gl.GetCapabilities()->SupportsImplicitResolvingMSAA() &&
536 std::optional<GLuint> resolve_fbo_opt;
542 if (!resolve_fbo_opt.has_value()) {
547 gl.BindFramebuffer(GL_FRAMEBUFFER, resolve_fbo_opt.value());
550 GL_FRAMEBUFFER, TextureGLES::AttachmentType::kColor0)) {
554 auto status = gl.CheckFramebufferStatusDebug(GL_FRAMEBUFFER);
555 if (status != GL_FRAMEBUFFER_COMPLETE) {
561 gl.BindFramebuffer(GL_FRAMEBUFFER, resolve_fbo_opt.value());
565 gl.BindFramebuffer(GL_READ_FRAMEBUFFER, fbo.value());
566 gl.BindFramebuffer(GL_DRAW_FRAMEBUFFER, resolve_fbo_opt.value());
568 RenderPassGLES::ResetGLState(gl);
571 gl.BlitFramebuffer(0,
582 gl.BindFramebuffer(GL_DRAW_FRAMEBUFFER, GL_NONE);
583 gl.BindFramebuffer(GL_READ_FRAMEBUFFER, GL_NONE);
585 gl.BindFramebuffer(GL_FRAMEBUFFER, fbo.value());
592 if (gl.InvalidateFramebuffer.IsAvailable()) {
593 std::array<GLenum, 3> attachments;
594 size_t attachment_count = 0;
596 bool angle_safe = gl.GetCapabilities()->IsANGLE() ? !is_default_fbo :
true;
599 attachments[attachment_count++] =
600 (is_default_fbo ? GL_COLOR_EXT : GL_COLOR_ATTACHMENT0);
604 attachments[attachment_count++] =
605 (is_default_fbo ? GL_DEPTH_EXT : GL_DEPTH_ATTACHMENT);
609 attachments[attachment_count++] =
610 (is_default_fbo ? GL_STENCIL_EXT : GL_STENCIL_ATTACHMENT);
612 gl.InvalidateFramebuffer(GL_FRAMEBUFFER,
616 }
else if (gl.DiscardFramebufferEXT.IsAvailable()) {
617 std::array<GLenum, 3> attachments;
618 size_t attachment_count = 0;
623 bool angle_safe = gl.GetCapabilities()->IsANGLE() ? !is_default_fbo :
true;
626 attachments[attachment_count++] =
627 (is_default_fbo ? GL_COLOR_EXT : GL_COLOR_ATTACHMENT0);
631 attachments[attachment_count++] =
632 (is_default_fbo ? GL_DEPTH_EXT : GL_DEPTH_ATTACHMENT);
636 attachments[attachment_count++] =
637 (is_default_fbo ? GL_STENCIL_EXT : GL_STENCIL_ATTACHMENT);
639 gl.DiscardFramebufferEXT(GL_FRAMEBUFFER,
646 if (is_default_fbo) {
647 tracer->MarkFrameEnd(gl);