Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions impeller/renderer/backend/gles/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ impeller_component("gles") {
"reactor_gles.h",
"render_pass_gles.cc",
"render_pass_gles.h",
"render_pass_gles3.cc",
"render_pass_gles3.h",
"render_pass_utils.cc",
"render_pass_utils.h",
"sampler_gles.cc",
"sampler_gles.h",
"sampler_library_gles.cc",
Expand Down
6 changes: 3 additions & 3 deletions impeller/renderer/backend/gles/buffer_bindings_gles.cc
Original file line number Diff line number Diff line change
Expand Up @@ -219,8 +219,8 @@ bool BufferBindingsGLES::BindVertexAttributes(const ProcTableGLES& gl,

bool BufferBindingsGLES::BindUniformData(
const ProcTableGLES& gl,
const std::vector<TextureAndSampler>& bound_textures,
const std::vector<BufferResource>& bound_buffers,
const TextureAndSampler bound_textures[],
const BufferResource bound_buffers[],
Comment on lines +222 to +223
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are you converting these to c arrays? It looks like everything going into this is a vector anways.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm using a fixed size std::array in render_pass_gles3.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missed that, thanks. We'll be able to use std::span in c++20.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

god I'm so ready for span

Range texture_range,
Range buffer_range) {
for (auto i = 0u; i < buffer_range.length; i++) {
Expand Down Expand Up @@ -444,7 +444,7 @@ bool BufferBindingsGLES::BindUniformBufferV2(

std::optional<size_t> BufferBindingsGLES::BindTextures(
const ProcTableGLES& gl,
const std::vector<TextureAndSampler>& bound_textures,
const TextureAndSampler bound_textures[],
Range texture_range,
ShaderStage stage,
size_t unit_start_index) {
Expand Down
15 changes: 7 additions & 8 deletions impeller/renderer/backend/gles/buffer_bindings_gles.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ class BufferBindingsGLES {
size_t vertex_offset);

bool BindUniformData(const ProcTableGLES& gl,
const std::vector<TextureAndSampler>& bound_textures,
const std::vector<BufferResource>& bound_buffers,
const TextureAndSampler bound_textures[],
const BufferResource bound_buffers[],
Range texture_range,
Range buffer_range);

Expand Down Expand Up @@ -95,12 +95,11 @@ class BufferBindingsGLES {
const ShaderMetadata* metadata,
const DeviceBufferGLES& device_buffer_gles);

std::optional<size_t> BindTextures(
const ProcTableGLES& gl,
const std::vector<TextureAndSampler>& bound_textures,
Range texture_range,
ShaderStage stage,
size_t unit_start_index = 0);
std::optional<size_t> BindTextures(const ProcTableGLES& gl,
const TextureAndSampler bound_textures[],
Range texture_range,
ShaderStage stage,
size_t unit_start_index = 0);

BufferBindingsGLES(const BufferBindingsGLES&) = delete;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ TEST(BufferBindingsGLESTest, BindUniformData) {
BufferView buffer_view(&device_buffer, Range(0, sizeof(float)));
bound_buffers.push_back(BufferResource(&shader_metadata, buffer_view));

EXPECT_TRUE(bindings.BindUniformData(mock_gl->GetProcTable(), bound_textures,
bound_buffers, Range{0, 0},
Range{0, 1}));
EXPECT_TRUE(
bindings.BindUniformData(mock_gl->GetProcTable(), bound_textures.data(),
bound_buffers.data(), Range{0, 0}, Range{0, 1}));
}

} // namespace testing
Expand Down
11 changes: 11 additions & 0 deletions impeller/renderer/backend/gles/command_buffer_gles.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "impeller/base/config.h"
#include "impeller/renderer/backend/gles/blit_pass_gles.h"
#include "impeller/renderer/backend/gles/render_pass_gles.h"
#include "impeller/renderer/backend/gles/render_pass_gles3.h"

namespace impeller {

Expand Down Expand Up @@ -58,6 +59,16 @@ std::shared_ptr<RenderPass> CommandBufferGLES::OnCreateRenderPass(
if (!context) {
return nullptr;
}
if (reactor_->GetProcTable().GetDescription()->GetGlVersion().IsAtLeast(
Version{3, 0, 0}) &&
reactor_->CanReactOnCurrentThread()) {
auto pass = std::shared_ptr<RenderPassGLES3>(
new RenderPassGLES3(context, target, reactor_));
if (!pass->IsValid()) {
return nullptr;
}
return pass;
}
auto pass = std::shared_ptr<RenderPassGLES>(
new RenderPassGLES(context, target, reactor_));
if (!pass->IsValid()) {
Expand Down
1 change: 1 addition & 0 deletions impeller/renderer/backend/gles/context_gles.cc
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ ContextGLES::ContextGLES(
gpu_tracer_ = std::make_shared<GPUTracerGLES>(GetReactor()->GetProcTable(),
enable_gpu_tracing);
command_queue_ = std::make_shared<CommandQueue>();
global_state_ = std::make_shared<GlobalStateGLES>();
is_valid_ = true;
}

Expand Down
10 changes: 10 additions & 0 deletions impeller/renderer/backend/gles/context_gles.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#define FLUTTER_IMPELLER_RENDERER_BACKEND_GLES_CONTEXT_GLES_H_

#include "impeller/base/backend_cast.h"
#include "impeller/core/formats.h"
#include "impeller/core/runtime_types.h"
#include "impeller/renderer/backend/gles/allocator_gles.h"
#include "impeller/renderer/backend/gles/capabilities_gles.h"
Expand All @@ -20,6 +21,12 @@

namespace impeller {

struct GlobalStateGLES {
GLuint fbo_id = GL_NONE;
std::optional<Viewport> viewport = std::nullopt;
std::optional<ISize> target_size = std::nullopt;
};

class ContextGLES final : public Context,
public BackendCast<ContextGLES, Context>,
public std::enable_shared_from_this<ContextGLES> {
Expand All @@ -44,13 +51,16 @@ class ContextGLES final : public Context,

std::shared_ptr<GPUTracerGLES> GetGPUTracer() const { return gpu_tracer_; }

GlobalStateGLES* GetGlobalState() const { return global_state_.get(); }

private:
std::shared_ptr<ReactorGLES> reactor_;
std::shared_ptr<ShaderLibraryGLES> shader_library_;
std::shared_ptr<PipelineLibraryGLES> pipeline_library_;
std::shared_ptr<SamplerLibraryGLES> sampler_library_;
std::shared_ptr<AllocatorGLES> resource_allocator_;
std::shared_ptr<CommandQueue> command_queue_;
std::shared_ptr<GlobalStateGLES> global_state_;
std::shared_ptr<GPUTracerGLES> gpu_tracer_;

// Note: This is stored separately from the ProcTableGLES CapabilitiesGLES
Expand Down
14 changes: 11 additions & 3 deletions impeller/renderer/backend/gles/device_buffer_gles.cc
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,17 @@ bool DeviceBufferGLES::BindAndUploadDataIfNecessary(BindingType type) const {
}

if (dirty_range_.has_value()) {
auto range = dirty_range_.value();
gl.BufferSubData(target_type, range.offset, range.length,
backing_store_->GetBuffer() + range.offset);
Range range = dirty_range_.value();
if (gl.MapBufferRange.IsAvailable()) {
void* data =
gl.MapBufferRange(target_type, range.offset, range.length,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So at least locally for me, this is the trick that is letting us incrementally write to the device buffers like we do for vulkan/metal. I believe this will be faster but it likely needs a run through the devicelab to confirm.

GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
::memcpy(data, backing_store_->GetBuffer() + range.offset, range.length);
gl.UnmapBuffer(target_type);
} else {
gl.BufferSubData(target_type, range.offset, range.length,
backing_store_->GetBuffer() + range.offset);
}
dirty_range_ = std::nullopt;
}

Expand Down
2 changes: 2 additions & 0 deletions impeller/renderer/backend/gles/proc_table_gles.h
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,8 @@ void(glDepthRange)(GLdouble n, GLdouble f);
#define FOR_EACH_IMPELLER_GLES3_PROC(PROC) \
PROC(FenceSync); \
PROC(DeleteSync); \
PROC(MapBufferRange); \
PROC(UnmapBuffer); \
PROC(GetActiveUniformBlockiv); \
PROC(GetActiveUniformBlockName); \
PROC(GetUniformBlockIndex); \
Expand Down
4 changes: 2 additions & 2 deletions impeller/renderer/backend/gles/reactor_gles.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ class ReactorGLES {
///
const ProcTableGLES& GetProcTable() const;

bool CanReactOnCurrentThread() const;

//----------------------------------------------------------------------------
/// @brief Returns the OpenGL handle for a reactor handle if one is
/// available. This is typically only safe to call within a
Expand Down Expand Up @@ -306,8 +308,6 @@ class ReactorGLES {

bool HasPendingOperations() const;

bool CanReactOnCurrentThread() const;

bool ConsolidateHandles();

bool FlushOps();
Expand Down
137 changes: 3 additions & 134 deletions impeller/renderer/backend/gles/render_pass_gles.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "impeller/renderer/backend/gles/formats_gles.h"
#include "impeller/renderer/backend/gles/gpu_tracer_gles.h"
#include "impeller/renderer/backend/gles/pipeline_gles.h"
#include "impeller/renderer/backend/gles/render_pass_utils.h"
#include "impeller/renderer/backend/gles/texture_gles.h"
#include "impeller/renderer/command.h"

Expand All @@ -43,138 +44,6 @@ void RenderPassGLES::OnSetLabel(std::string_view label) {
label_ = label;
}

void ConfigureBlending(const ProcTableGLES& gl,
const ColorAttachmentDescriptor* color) {
if (color->blending_enabled) {
gl.Enable(GL_BLEND);
gl.BlendFuncSeparate(
ToBlendFactor(color->src_color_blend_factor), // src color
ToBlendFactor(color->dst_color_blend_factor), // dst color
ToBlendFactor(color->src_alpha_blend_factor), // src alpha
ToBlendFactor(color->dst_alpha_blend_factor) // dst alpha
);
gl.BlendEquationSeparate(
ToBlendOperation(color->color_blend_op), // mode color
ToBlendOperation(color->alpha_blend_op) // mode alpha
);
} else {
gl.Disable(GL_BLEND);
}

{
const auto is_set = [](ColorWriteMask mask,
ColorWriteMask check) -> GLboolean {
return (mask & check) ? GL_TRUE : GL_FALSE;
};

gl.ColorMask(
is_set(color->write_mask, ColorWriteMaskBits::kRed), // red
is_set(color->write_mask, ColorWriteMaskBits::kGreen), // green
is_set(color->write_mask, ColorWriteMaskBits::kBlue), // blue
is_set(color->write_mask, ColorWriteMaskBits::kAlpha) // alpha
);
}
}

void ConfigureStencil(GLenum face,
const ProcTableGLES& gl,
const StencilAttachmentDescriptor& stencil,
uint32_t stencil_reference) {
gl.StencilOpSeparate(
face, // face
ToStencilOp(stencil.stencil_failure), // stencil fail
ToStencilOp(stencil.depth_failure), // depth fail
ToStencilOp(stencil.depth_stencil_pass) // depth stencil pass
);
gl.StencilFuncSeparate(face, // face
ToCompareFunction(stencil.stencil_compare), // func
stencil_reference, // ref
stencil.read_mask // mask
);
gl.StencilMaskSeparate(face, stencil.write_mask);
}

void ConfigureStencil(const ProcTableGLES& gl,
const PipelineDescriptor& pipeline,
uint32_t stencil_reference) {
if (!pipeline.HasStencilAttachmentDescriptors()) {
gl.Disable(GL_STENCIL_TEST);
return;
}

gl.Enable(GL_STENCIL_TEST);
const auto& front = pipeline.GetFrontStencilAttachmentDescriptor();
const auto& back = pipeline.GetBackStencilAttachmentDescriptor();

if (front.has_value() && back.has_value() && front == back) {
ConfigureStencil(GL_FRONT_AND_BACK, gl, *front, stencil_reference);
return;
}
if (front.has_value()) {
ConfigureStencil(GL_FRONT, gl, *front, stencil_reference);
}
if (back.has_value()) {
ConfigureStencil(GL_BACK, gl, *back, stencil_reference);
}
}

//------------------------------------------------------------------------------
/// @brief Encapsulates data that will be needed in the reactor for the
/// encoding of commands for this render pass.
///
struct RenderPassData {
Viewport viewport;

Color clear_color;
uint32_t clear_stencil = 0u;
Scalar clear_depth = 1.0;

std::shared_ptr<Texture> color_attachment;
std::shared_ptr<Texture> depth_attachment;
std::shared_ptr<Texture> stencil_attachment;

bool clear_color_attachment = true;
bool clear_depth_attachment = true;
bool clear_stencil_attachment = true;

bool discard_color_attachment = true;
bool discard_depth_attachment = true;
bool discard_stencil_attachment = true;

std::string label;
};

static bool BindVertexBuffer(const ProcTableGLES& gl,
BufferBindingsGLES* vertex_desc_gles,
const BufferView& vertex_buffer_view,
size_t buffer_index) {
if (!vertex_buffer_view) {
return false;
}

const DeviceBuffer* vertex_buffer = vertex_buffer_view.GetBuffer();

if (!vertex_buffer) {
return false;
}

const auto& vertex_buffer_gles = DeviceBufferGLES::Cast(*vertex_buffer);
if (!vertex_buffer_gles.BindAndUploadDataIfNecessary(
DeviceBufferGLES::BindingType::kArrayBuffer)) {
return false;
}

//--------------------------------------------------------------------------
/// Bind the vertex attributes associated with vertex buffer.
///
if (!vertex_desc_gles->BindVertexAttributes(
gl, buffer_index, vertex_buffer_view.GetRange().offset)) {
return false;
}

return true;
}

void RenderPassGLES::ResetGLState(const ProcTableGLES& gl) {
gl.Disable(GL_SCISSOR_TEST);
gl.Disable(GL_DEPTH_TEST);
Expand Down Expand Up @@ -463,8 +332,8 @@ void RenderPassGLES::ResetGLState(const ProcTableGLES& gl) {
///
if (!vertex_desc_gles->BindUniformData(
gl, //
bound_textures, //
bound_buffers, //
bound_textures.data(), //
bound_buffers.data(), //
/*texture_range=*/command.bound_textures, //
/*buffer_range=*/command.bound_buffers //
)) {
Expand Down
Loading
Loading