[Impeller] set GLES viewport once, remove extra unbind/validation. (flutter/engine#56902)

Small cleanups to render_pass_gles to only set the viewport once or when it cahnges, instead of each draw. Removes scissor validation and pipeline unbind (which is slow due to hash table lookup).
This commit is contained in:
Jonah Williams 2024-12-02 17:19:18 -08:00 committed by GitHub
parent 14ae687eac
commit 52504d1d77
2 changed files with 39 additions and 34 deletions

View File

@ -196,7 +196,6 @@ void RenderPassGLES::ResetGLState(const ProcTableGLES& gl) {
const auto& gl = reactor.GetProcTable();
#ifdef IMPELLER_DEBUG
tracer->MarkFrameStart(gl);
#endif // IMPELLER_DEBUG
fml::ScopedCleanupClosure pop_pass_debug_marker(
[&gl]() { gl.PopDebugGroup(); });
@ -205,6 +204,7 @@ void RenderPassGLES::ResetGLState(const ProcTableGLES& gl) {
} else {
pop_pass_debug_marker.Release();
}
#endif // IMPELLER_DEBUG
GLuint fbo = GL_NONE;
TextureGLES& color_gles = TextureGLES::Cast(*pass_data.color_attachment);
@ -285,6 +285,29 @@ void RenderPassGLES::ResetGLState(const ProcTableGLES& gl) {
gl.Clear(clear_bits);
// Both the viewport and scissor are specified in framebuffer coordinates.
// Impeller's framebuffer coordinate system is top left origin, but OpenGL's
// is bottom left origin, so we convert the coordinates here.
auto target_size = pass_data.color_attachment->GetSize();
//--------------------------------------------------------------------------
/// Setup the viewport.
///
const auto& viewport = pass_data.viewport;
gl.Viewport(viewport.rect.GetX(), // x
target_size.height - viewport.rect.GetY() -
viewport.rect.GetHeight(), // y
viewport.rect.GetWidth(), // width
viewport.rect.GetHeight() // height
);
if (pass_data.depth_attachment) {
if (gl.DepthRangef.IsAvailable()) {
gl.DepthRangef(viewport.depth_range.z_near, viewport.depth_range.z_far);
} else {
gl.DepthRange(viewport.depth_range.z_near, viewport.depth_range.z_far);
}
}
for (const auto& command : commands) {
if (command.instance_count != 1u) {
VALIDATION_LOG << "GLES backend does not support instanced rendering.";
@ -339,26 +362,24 @@ void RenderPassGLES::ResetGLState(const ProcTableGLES& gl) {
gl.Disable(GL_DEPTH_TEST);
}
// Both the viewport and scissor are specified in framebuffer coordinates.
// Impeller's framebuffer coordinate system is top left origin, but OpenGL's
// is bottom left origin, so we convert the coordinates here.
auto target_size = pass_data.color_attachment->GetSize();
//--------------------------------------------------------------------------
/// Setup the viewport.
///
const auto& viewport = command.viewport.value_or(pass_data.viewport);
gl.Viewport(viewport.rect.GetX(), // x
target_size.height - viewport.rect.GetY() -
viewport.rect.GetHeight(), // y
viewport.rect.GetWidth(), // width
viewport.rect.GetHeight() // height
);
if (pass_data.depth_attachment) {
if (gl.DepthRangef.IsAvailable()) {
gl.DepthRangef(viewport.depth_range.z_near, viewport.depth_range.z_far);
} else {
gl.DepthRange(viewport.depth_range.z_near, viewport.depth_range.z_far);
if (command.viewport.has_value()) {
gl.Viewport(viewport.rect.GetX(), // x
target_size.height - viewport.rect.GetY() -
viewport.rect.GetHeight(), // y
viewport.rect.GetWidth(), // width
viewport.rect.GetHeight() // height
);
if (pass_data.depth_attachment) {
if (gl.DepthRangef.IsAvailable()) {
gl.DepthRangef(viewport.depth_range.z_near,
viewport.depth_range.z_far);
} else {
gl.DepthRange(viewport.depth_range.z_near,
viewport.depth_range.z_far);
}
}
}
@ -481,13 +502,6 @@ void RenderPassGLES::ResetGLState(const ProcTableGLES& gl) {
if (!vertex_desc_gles->UnbindVertexAttributes(gl)) {
return false;
}
//--------------------------------------------------------------------------
/// Unbind the program pipeline.
///
if (!pipeline.UnbindProgram()) {
return false;
}
}
if (gl.DiscardFramebufferEXT.IsAvailable()) {

View File

@ -63,15 +63,6 @@ bool RenderPass::AddCommand(Command&& command) {
return false;
}
if (command.scissor.has_value()) {
auto target_rect = IRect::MakeSize(render_target_.GetRenderTargetSize());
if (!target_rect.Contains(command.scissor.value())) {
VALIDATION_LOG << "Cannot apply a scissor that lies outside the bounds "
"of the render target.";
return false;
}
}
if (command.element_count == 0u || command.instance_count == 0u) {
// Essentially a no-op. Don't record the command but this is not necessary
// an error either.