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 TRACE_EVENT0(
"impeller",
"RenderPassGLES::EncodeCommandsInReactor");
204 tracer->MarkFrameStart(gl);
207 [&gl]() { gl.PopDebugGroup(); });
208 if (!pass_data.
label.empty()) {
209 gl.PushDebugGroup(pass_data.
label);
211 pop_pass_debug_marker.
Release();
216 const bool is_wrapped_fbo = color_gles.
IsWrapped();
218 std::optional<GLuint> fbo = 0;
219 if (is_wrapped_fbo) {
220 if (color_gles.
GetFBO().has_value()) {
222 gl.BindFramebuffer(GL_FRAMEBUFFER, *color_gles.
GetFBO());
228 if (!fbo.has_value()) {
231 gl.BindFramebuffer(GL_FRAMEBUFFER, fbo.value());
237 if (!fbo.has_value()) {
240 gl.BindFramebuffer(GL_FRAMEBUFFER, fbo.value());
243 GL_FRAMEBUFFER, TextureGLES::AttachmentType::kColor0)) {
248 if (!depth->SetAsFramebufferAttachment(
249 GL_FRAMEBUFFER, TextureGLES::AttachmentType::kDepth)) {
255 if (!stencil->SetAsFramebufferAttachment(
256 GL_FRAMEBUFFER, TextureGLES::AttachmentType::kStencil)) {
261 auto status = gl.CheckFramebufferStatus(GL_FRAMEBUFFER);
262 if (status != GL_FRAMEBUFFER_COMPLETE) {
276 if (gl.DepthRangef.IsAvailable()) {
286 GLenum clear_bits = 0u;
288 clear_bits |= GL_COLOR_BUFFER_BIT;
291 clear_bits |= GL_DEPTH_BUFFER_BIT;
294 clear_bits |= GL_STENCIL_BUFFER_BIT;
297 RenderPassGLES::ResetGLState(gl);
299 gl.Clear(clear_bits);
309 const auto& viewport = pass_data.
viewport;
310 gl.Viewport(viewport.rect.GetX(),
311 target_size.
height - viewport.rect.GetY() -
312 viewport.rect.GetHeight(),
313 viewport.rect.GetWidth(),
314 viewport.rect.GetHeight()
317 if (gl.DepthRangef.IsAvailable()) {
318 gl.DepthRangef(viewport.depth_range.z_near, viewport.depth_range.z_far);
320 gl.DepthRange(viewport.depth_range.z_near, viewport.depth_range.z_far);
324 CullMode current_cull_mode = CullMode::kNone;
325 WindingOrder current_winding_order = WindingOrder::kClockwise;
328 for (
const auto& command : commands) {
331 [&gl]() { gl.PopDebugGroup(); });
332 if (!command.label.empty()) {
333 gl.PushDebugGroup(command.label);
335 pop_cmd_debug_marker.
Release();
339 const auto& pipeline = PipelineGLES::Cast(*command.pipeline);
341 const auto* color_attachment =
342 pipeline.GetDescriptor().GetLegacyCompatibleColorAttachment();
343 if (!color_attachment) {
345 <<
"Color attachment is too complicated for a legacy renderer.";
363 pipeline.GetDescriptor().GetDepthStencilAttachmentDescriptor();
365 gl.Enable(GL_DEPTH_TEST);
367 gl.DepthMask(depth->depth_write_enabled ? GL_TRUE : GL_FALSE);
369 gl.Disable(GL_DEPTH_TEST);
375 if (command.viewport.has_value()) {
376 gl.Viewport(viewport.rect.GetX(),
377 target_size.
height - viewport.rect.GetY() -
378 viewport.rect.GetHeight(),
379 viewport.rect.GetWidth(),
380 viewport.rect.GetHeight()
383 if (gl.DepthRangef.IsAvailable()) {
384 gl.DepthRangef(viewport.depth_range.z_near,
385 viewport.depth_range.z_far);
387 gl.DepthRange(viewport.depth_range.z_near,
388 viewport.depth_range.z_far);
396 if (command.scissor.has_value()) {
397 const auto& scissor = command.scissor.value();
398 gl.Enable(GL_SCISSOR_TEST);
401 target_size.
height - scissor.GetY() - scissor.GetHeight(),
410 CullMode pipeline_cull_mode = pipeline.GetDescriptor().GetCullMode();
411 if (current_cull_mode != pipeline_cull_mode) {
412 switch (pipeline_cull_mode) {
413 case CullMode::kNone:
414 gl.Disable(GL_CULL_FACE);
416 case CullMode::kFrontFace:
417 gl.Enable(GL_CULL_FACE);
418 gl.CullFace(GL_FRONT);
420 case CullMode::kBackFace:
421 gl.Enable(GL_CULL_FACE);
422 gl.CullFace(GL_BACK);
425 current_cull_mode = pipeline_cull_mode;
432 pipeline.GetDescriptor().GetWindingOrder();
433 if (current_winding_order != pipeline_winding_order) {
434 switch (pipeline.GetDescriptor().GetWindingOrder()) {
435 case WindingOrder::kClockwise:
438 case WindingOrder::kCounterClockwise:
439 gl.FrontFace(GL_CCW);
442 current_winding_order = pipeline_winding_order;
454 for (
size_t i = 0;
i < command.vertex_buffers.length;
i++) {
456 vertex_buffers[
i + command.vertex_buffers.offset],
465 if (!pipeline.BindProgram()) {
476 command.bound_textures,
477 command.bound_buffers
491 pipeline.GetDescriptor().GetPolygonMode() == PolygonMode::kLine
493 :
ToMode(pipeline.GetDescriptor().GetPrimitiveType());
498 if (command.index_type == IndexType::kNone) {
499 gl.DrawArrays(mode, command.base_vertex, command.element_count);
502 auto index_buffer_view = command.index_buffer;
503 const DeviceBuffer* index_buffer = index_buffer_view.GetBuffer();
504 const auto& index_buffer_gles = DeviceBufferGLES::Cast(*index_buffer);
505 if (!index_buffer_gles.BindAndUploadDataIfNecessary(
506 DeviceBufferGLES::BindingType::kElementArrayBuffer)) {
509 gl.DrawElements(mode,
510 command.element_count,
512 reinterpret_cast<const GLvoid*
>(
static_cast<GLsizei
>(
513 index_buffer_view.GetRange().offset))
526 !gl.GetCapabilities()->SupportsImplicitResolvingMSAA() &&
532 gl.GenFramebuffers(1u, &resolve_fbo);
533 gl.BindFramebuffer(GL_FRAMEBUFFER, resolve_fbo);
536 .SetAsFramebufferAttachment(
537 GL_FRAMEBUFFER, TextureGLES::AttachmentType::kColor0)) {
541 auto status = gl.CheckFramebufferStatus(GL_FRAMEBUFFER);
542 if (gl.CheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
549 gl.BindFramebuffer(GL_READ_FRAMEBUFFER, fbo.value());
550 gl.BindFramebuffer(GL_DRAW_FRAMEBUFFER, resolve_fbo);
552 RenderPassGLES::ResetGLState(gl);
555 gl.BlitFramebuffer(0,
566 gl.BindFramebuffer(GL_DRAW_FRAMEBUFFER, GL_NONE);
567 gl.BindFramebuffer(GL_READ_FRAMEBUFFER, GL_NONE);
568 gl.DeleteFramebuffers(1u, &resolve_fbo);
570 gl.BindFramebuffer(GL_FRAMEBUFFER, fbo.value());
577 if (gl.DiscardFramebufferEXT.IsAvailable()) {
578 std::array<GLenum, 3> attachments;
579 size_t attachment_count = 0;
584 bool angle_safe = gl.GetCapabilities()->IsANGLE() ? !is_default_fbo :
true;
587 attachments[attachment_count++] =
588 (is_default_fbo ? GL_COLOR_EXT : GL_COLOR_ATTACHMENT0);
592 attachments[attachment_count++] =
593 (is_default_fbo ? GL_DEPTH_EXT : GL_DEPTH_ATTACHMENT);
597 attachments[attachment_count++] =
598 (is_default_fbo ? GL_STENCIL_EXT : GL_STENCIL_ATTACHMENT);
600 gl.DiscardFramebufferEXT(GL_FRAMEBUFFER,
607 if (is_default_fbo) {
608 tracer->MarkFrameEnd(gl);