195 const std::vector<Command>& commands,
196 const std::vector<BufferView>& vertex_buffers,
197 const std::vector<TextureAndSampler>& bound_textures,
198 const std::vector<BufferResource>& bound_buffers,
199 const std::shared_ptr<GPUTracerGLES>& tracer,
200 const std::shared_ptr<const Context>& impeller_context) {
201 TRACE_EVENT0(
"impeller",
"RenderPassGLES::EncodeCommandsInReactor");
205 tracer->MarkFrameStart(gl);
208 [&gl]() { gl.PopDebugGroup(); });
209 if (!pass_data.
label.empty()) {
210 gl.PushDebugGroup(pass_data.
label);
212 pop_pass_debug_marker.
Release();
217 const bool is_wrapped_fbo = color_gles.
IsWrapped();
219 std::optional<GLuint> fbo = 0;
220 if (is_wrapped_fbo) {
221 if (color_gles.
GetFBO().has_value()) {
223 gl.BindFramebuffer(GL_FRAMEBUFFER, *color_gles.
GetFBO());
229 if (!fbo.has_value()) {
232 gl.BindFramebuffer(GL_FRAMEBUFFER, fbo.value());
238 if (!fbo.has_value()) {
241 gl.BindFramebuffer(GL_FRAMEBUFFER, fbo.value());
244 GL_FRAMEBUFFER, TextureGLES::AttachmentType::kColor0)) {
249 if (!depth->SetAsFramebufferAttachment(
250 GL_FRAMEBUFFER, TextureGLES::AttachmentType::kDepth)) {
256 if (!stencil->SetAsFramebufferAttachment(
257 GL_FRAMEBUFFER, TextureGLES::AttachmentType::kStencil)) {
262 auto status = gl.CheckFramebufferStatusDebug(GL_FRAMEBUFFER);
263 if (status != GL_FRAMEBUFFER_COMPLETE) {
277 if (gl.DepthRangef.IsAvailable()) {
287 GLenum clear_bits = 0u;
289 clear_bits |= GL_COLOR_BUFFER_BIT;
292 clear_bits |= GL_DEPTH_BUFFER_BIT;
295 clear_bits |= GL_STENCIL_BUFFER_BIT;
298 RenderPassGLES::ResetGLState(gl);
300 gl.Clear(clear_bits);
310 const auto& viewport = pass_data.
viewport;
311 gl.Viewport(viewport.rect.GetX(),
312 target_size.
height - viewport.rect.GetY() -
313 viewport.rect.GetHeight(),
314 viewport.rect.GetWidth(),
315 viewport.rect.GetHeight()
318 if (gl.DepthRangef.IsAvailable()) {
319 gl.DepthRangef(viewport.depth_range.z_near, viewport.depth_range.z_far);
321 gl.DepthRange(viewport.depth_range.z_near, viewport.depth_range.z_far);
325 CullMode current_cull_mode = CullMode::kNone;
326 WindingOrder current_winding_order = WindingOrder::kClockwise;
329 for (
const auto& command : commands) {
332 [&gl]() { gl.PopDebugGroup(); });
333 if (!command.label.empty()) {
334 gl.PushDebugGroup(command.label);
336 pop_cmd_debug_marker.
Release();
339 const auto& pipeline = PipelineGLES::Cast(*command.pipeline);
340 impeller_context->GetPipelineLibrary()->LogPipelineUsage(
341 pipeline.GetDescriptor());
342 const auto* color_attachment =
343 pipeline.GetDescriptor().GetLegacyCompatibleColorAttachment();
344 if (!color_attachment) {
346 <<
"Color attachment is too complicated for a legacy renderer.";
364 pipeline.GetDescriptor().GetDepthStencilAttachmentDescriptor();
366 gl.Enable(GL_DEPTH_TEST);
368 gl.DepthMask(depth->depth_write_enabled ? GL_TRUE : GL_FALSE);
370 gl.Disable(GL_DEPTH_TEST);
376 if (command.viewport.has_value()) {
377 gl.Viewport(viewport.rect.GetX(),
378 target_size.
height - viewport.rect.GetY() -
379 viewport.rect.GetHeight(),
380 viewport.rect.GetWidth(),
381 viewport.rect.GetHeight()
384 if (gl.DepthRangef.IsAvailable()) {
385 gl.DepthRangef(viewport.depth_range.z_near,
386 viewport.depth_range.z_far);
388 gl.DepthRange(viewport.depth_range.z_near,
389 viewport.depth_range.z_far);
397 if (command.scissor.has_value()) {
398 const auto& scissor = command.scissor.value();
399 gl.Enable(GL_SCISSOR_TEST);
402 target_size.
height - scissor.GetY() - scissor.GetHeight(),
411 CullMode pipeline_cull_mode = pipeline.GetDescriptor().GetCullMode();
412 if (current_cull_mode != pipeline_cull_mode) {
413 switch (pipeline_cull_mode) {
414 case CullMode::kNone:
415 gl.Disable(GL_CULL_FACE);
417 case CullMode::kFrontFace:
418 gl.Enable(GL_CULL_FACE);
419 gl.CullFace(GL_FRONT);
421 case CullMode::kBackFace:
422 gl.Enable(GL_CULL_FACE);
423 gl.CullFace(GL_BACK);
426 current_cull_mode = pipeline_cull_mode;
433 pipeline.GetDescriptor().GetWindingOrder();
434 if (current_winding_order != pipeline_winding_order) {
435 switch (pipeline.GetDescriptor().GetWindingOrder()) {
436 case WindingOrder::kClockwise:
439 case WindingOrder::kCounterClockwise:
440 gl.FrontFace(GL_CCW);
443 current_winding_order = pipeline_winding_order;
455 for (
size_t i = 0;
i < command.vertex_buffers.length;
i++) {
457 vertex_buffers[
i + command.vertex_buffers.offset],
466 if (!pipeline.BindProgram()) {
477 command.bound_textures,
478 command.bound_buffers
492 pipeline.GetDescriptor().GetPolygonMode() == PolygonMode::kLine
494 :
ToMode(pipeline.GetDescriptor().GetPrimitiveType());
499 if (command.index_type == IndexType::kNone) {
500 gl.DrawArrays(mode, command.base_vertex, command.element_count);
503 auto index_buffer_view = command.index_buffer;
504 const DeviceBuffer* index_buffer = index_buffer_view.GetBuffer();
505 const auto& index_buffer_gles = DeviceBufferGLES::Cast(*index_buffer);
506 if (!index_buffer_gles.BindAndUploadDataIfNecessary(
507 DeviceBufferGLES::BindingType::kElementArrayBuffer)) {
510 gl.DrawElements(mode,
511 command.element_count,
513 reinterpret_cast<const GLvoid*
>(
static_cast<GLsizei
>(
514 index_buffer_view.GetRange().offset))
527 !gl.GetCapabilities()->SupportsImplicitResolvingMSAA() &&
533 gl.GenFramebuffers(1u, &resolve_fbo);
534 gl.BindFramebuffer(GL_FRAMEBUFFER, resolve_fbo);
537 .SetAsFramebufferAttachment(
538 GL_FRAMEBUFFER, TextureGLES::AttachmentType::kColor0)) {
542 auto status = gl.CheckFramebufferStatusDebug(GL_FRAMEBUFFER);
543 if (status != GL_FRAMEBUFFER_COMPLETE) {
550 gl.BindFramebuffer(GL_READ_FRAMEBUFFER, fbo.value());
551 gl.BindFramebuffer(GL_DRAW_FRAMEBUFFER, resolve_fbo);
553 RenderPassGLES::ResetGLState(gl);
556 gl.BlitFramebuffer(0,
567 gl.BindFramebuffer(GL_DRAW_FRAMEBUFFER, GL_NONE);
568 gl.BindFramebuffer(GL_READ_FRAMEBUFFER, GL_NONE);
569 gl.DeleteFramebuffers(1u, &resolve_fbo);
571 gl.BindFramebuffer(GL_FRAMEBUFFER, fbo.value());
578 if (gl.DiscardFramebufferEXT.IsAvailable()) {
579 std::array<GLenum, 3> attachments;
580 size_t attachment_count = 0;
585 bool angle_safe = gl.GetCapabilities()->IsANGLE() ? !is_default_fbo :
true;
588 attachments[attachment_count++] =
589 (is_default_fbo ? GL_COLOR_EXT : GL_COLOR_ATTACHMENT0);
593 attachments[attachment_count++] =
594 (is_default_fbo ? GL_DEPTH_EXT : GL_DEPTH_ATTACHMENT);
598 attachments[attachment_count++] =
599 (is_default_fbo ? GL_STENCIL_EXT : GL_STENCIL_ATTACHMENT);
601 gl.DiscardFramebufferEXT(GL_FRAMEBUFFER,
608 if (is_default_fbo) {
609 tracer->MarkFrameEnd(gl);