Skip to content

Commit

Permalink
[Impeller] GLES: Keep track of OpenGL ES device capabilities. (flutte…
Browse files Browse the repository at this point in the history
  • Loading branch information
chinmaygarde authored May 26, 2022
1 parent 45f74b5 commit bdb713c
Show file tree
Hide file tree
Showing 11 changed files with 210 additions and 8 deletions.
2 changes: 2 additions & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,8 @@ FILE: ../../../flutter/impeller/renderer/backend/gles/allocator_gles.cc
FILE: ../../../flutter/impeller/renderer/backend/gles/allocator_gles.h
FILE: ../../../flutter/impeller/renderer/backend/gles/buffer_bindings_gles.cc
FILE: ../../../flutter/impeller/renderer/backend/gles/buffer_bindings_gles.h
FILE: ../../../flutter/impeller/renderer/backend/gles/capabilities_gles.cc
FILE: ../../../flutter/impeller/renderer/backend/gles/capabilities_gles.h
FILE: ../../../flutter/impeller/renderer/backend/gles/command_buffer_gles.cc
FILE: ../../../flutter/impeller/renderer/backend/gles/command_buffer_gles.h
FILE: ../../../flutter/impeller/renderer/backend/gles/context_gles.cc
Expand Down
2 changes: 2 additions & 0 deletions impeller/renderer/backend/gles/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ impeller_component("gles") {
"allocator_gles.h",
"buffer_bindings_gles.cc",
"buffer_bindings_gles.h",
"capabilities_gles.cc",
"capabilities_gles.h",
"command_buffer_gles.cc",
"command_buffer_gles.h",
"context_gles.cc",
Expand Down
15 changes: 8 additions & 7 deletions impeller/renderer/backend/gles/buffer_bindings_gles.cc
Original file line number Diff line number Diff line change
Expand Up @@ -157,11 +157,11 @@ bool BufferBindingsGLES::BindUniformData(
}
}

if (!BindTextures(gl, vertex_bindings)) {
if (!BindTextures(gl, vertex_bindings, ShaderStage::kVertex)) {
return false;
}

if (!BindTextures(gl, fragment_bindings)) {
if (!BindTextures(gl, fragment_bindings, ShaderStage::kFragment)) {
return false;
}

Expand Down Expand Up @@ -276,7 +276,8 @@ bool BufferBindingsGLES::BindUniformBuffer(const ProcTableGLES& gl,
}

bool BufferBindingsGLES::BindTextures(const ProcTableGLES& gl,
const Bindings& bindings) const {
const Bindings& bindings,
ShaderStage stage) const {
size_t active_index = 0;
for (const auto& texture : bindings.textures) {
const auto& texture_gles = TextureGLES::Cast(*texture.second.resource);
Expand All @@ -295,12 +296,12 @@ bool BufferBindingsGLES::BindTextures(const ProcTableGLES& gl,
//--------------------------------------------------------------------------
/// Set the active texture unit.
///
const auto texture_index = GL_TEXTURE0 + active_index;
if (texture_index >= GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS) {
VALIDATION_LOG << "Active texture index was out of bounds.";
if (active_index >= gl.GetCapabilities()->GetMaxTextureUnits(stage)) {
VALIDATION_LOG << "Texture units specified exceed the capabilities for "
"this shader stage.";
return false;
}
gl.ActiveTexture(texture_index);
gl.ActiveTexture(GL_TEXTURE0 + active_index);

//--------------------------------------------------------------------------
/// Bind the texture.
Expand Down
4 changes: 3 additions & 1 deletion impeller/renderer/backend/gles/buffer_bindings_gles.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@ class BufferBindingsGLES {
Allocator& transients_allocator,
const BufferResource& buffer) const;

bool BindTextures(const ProcTableGLES& gl, const Bindings& bindings) const;
bool BindTextures(const ProcTableGLES& gl,
const Bindings& bindings,
ShaderStage stage) const;

FML_DISALLOW_COPY_AND_ASSIGN(BufferBindingsGLES);
};
Expand Down
106 changes: 106 additions & 0 deletions impeller/renderer/backend/gles/capabilities_gles.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "impeller/renderer/backend/gles/capabilities_gles.h"

#include "impeller/renderer/backend/gles/proc_table_gles.h"

namespace impeller {

CapabilitiesGLES::CapabilitiesGLES(const ProcTableGLES& gl) {
{
GLint value = 0;
gl.GetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &value);
max_combined_texture_image_units = value;
}

{
GLint value = 0;
gl.GetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &value);
max_cube_map_texture_size = value;
}

if (gl.GetDescription()->IsES()) {
GLint value = 0;
gl.GetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, &value);
max_fragment_uniform_vectors = value;
}

{
GLint value = 0;
gl.GetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &value);
max_renderbuffer_size = value;
}

{
GLint value = 0;
gl.GetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &value);
max_texture_image_units = value;
}

{
GLint value = 0;
gl.GetIntegerv(GL_MAX_TEXTURE_SIZE, &value);
max_texture_size = ISize{value, value};
}

if (gl.GetDescription()->IsES()) {
GLint value = 0;
gl.GetIntegerv(GL_MAX_VARYING_VECTORS, &value);
max_varying_vectors = value;
}

{
GLint value = 0;
gl.GetIntegerv(GL_MAX_VERTEX_ATTRIBS, &value);
max_vertex_attribs = value;
}

{
GLint value = 0;
gl.GetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &value);
max_vertex_texture_image_units = value;
}

if (gl.GetDescription()->IsES()) {
GLint value = 0;
gl.GetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &value);
max_vertex_uniform_vectors = value;
}

{
GLint values[2] = {};
gl.GetIntegerv(GL_MAX_VIEWPORT_DIMS, values);
max_viewport_dims = ISize{values[0], values[1]};
}

{
GLint value = 0;
gl.GetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &value);
num_compressed_texture_formats = value;
}

if (gl.GetDescription()->IsES()) {
GLint value = 0;
gl.GetIntegerv(GL_NUM_SHADER_BINARY_FORMATS, &value);
num_shader_binary_formats = value;
}
}

size_t CapabilitiesGLES::GetMaxTextureUnits(ShaderStage stage) const {
switch (stage) {
case ShaderStage::kVertex:
return max_vertex_texture_image_units;
case ShaderStage::kFragment:
return max_texture_image_units;
case ShaderStage::kUnknown:
case ShaderStage::kTessellationControl:
case ShaderStage::kTessellationEvaluation:
case ShaderStage::kCompute:
return 0u;
}
FML_UNREACHABLE();
}

} // namespace impeller
62 changes: 62 additions & 0 deletions impeller/renderer/backend/gles/capabilities_gles.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#pragma once

#include <cstddef>

#include "flutter/fml/macros.h"
#include "impeller/geometry/size.h"
#include "impeller/renderer/shader_types.h"

namespace impeller {

class ProcTableGLES;

struct CapabilitiesGLES {
CapabilitiesGLES(const ProcTableGLES& gl);

// Must be at least 8.
size_t max_combined_texture_image_units = 8;

// Must be at least 16.
size_t max_cube_map_texture_size = 16;

// Must be at least 16.
size_t max_fragment_uniform_vectors = 16;

// Must be at least 1.
size_t max_renderbuffer_size = 1;

// Must be at least 8.
size_t max_texture_image_units = 8;

// Must be at least 64.
ISize max_texture_size = ISize{64, 64};

// Must be at least 8.
size_t max_varying_vectors = 8;

// Must be at least 8.
size_t max_vertex_attribs = 8;

// May be 0.
size_t max_vertex_texture_image_units = 0;

// Must be at least 128.
size_t max_vertex_uniform_vectors = 128;

// Must be at least display size.
ISize max_viewport_dims;

// May be 0.
size_t num_compressed_texture_formats = 0;

// May be 0.
size_t num_shader_binary_formats = 0;

size_t GetMaxTextureUnits(ShaderStage stage) const;
};

} // namespace impeller
4 changes: 4 additions & 0 deletions impeller/renderer/backend/gles/description_gles.cc
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,10 @@ std::string DescriptionGLES::GetString() const {
return stream.str();
}

bool DescriptionGLES::IsES() const {
return is_es_;
}

bool DescriptionGLES::HasExtension(const std::string& ext) const {
return extensions_.find(ext) != extensions_.end();
}
Expand Down
2 changes: 2 additions & 0 deletions impeller/renderer/backend/gles/description_gles.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ class DescriptionGLES {

bool IsValid() const;

bool IsES() const;

std::string GetString() const;

bool HasExtension(const std::string& ext) const;
Expand Down
6 changes: 6 additions & 0 deletions impeller/renderer/backend/gles/proc_table_gles.cc
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ ProcTableGLES::ProcTableGLES(Resolver resolver) {
DiscardFramebufferEXT.Reset();
}

capabilities_ = std::make_unique<CapabilitiesGLES>(*this);

is_valid_ = true;
}

Expand All @@ -130,6 +132,10 @@ const DescriptionGLES* ProcTableGLES::GetDescription() const {
return description_.get();
}

const CapabilitiesGLES* ProcTableGLES::GetCapabilities() const {
return capabilities_.get();
}

static const char* FramebufferStatusToString(GLenum status) {
switch (status) {
case GL_FRAMEBUFFER_COMPLETE:
Expand Down
4 changes: 4 additions & 0 deletions impeller/renderer/backend/gles/proc_table_gles.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "flutter/fml/logging.h"
#include "flutter/fml/macros.h"
#include "flutter/fml/mapping.h"
#include "impeller/renderer/backend/gles/capabilities_gles.h"
#include "impeller/renderer/backend/gles/description_gles.h"
#include "impeller/renderer/backend/gles/gles.h"

Expand Down Expand Up @@ -191,6 +192,8 @@ class ProcTableGLES {

const DescriptionGLES* GetDescription() const;

const CapabilitiesGLES* GetCapabilities() const;

std::string DescribeCurrentFramebuffer() const;

std::string GetProgramInfoLogString(GLuint program) const;
Expand All @@ -208,6 +211,7 @@ class ProcTableGLES {
private:
bool is_valid_ = false;
std::unique_ptr<DescriptionGLES> description_;
std::unique_ptr<CapabilitiesGLES> capabilities_;
GLint debug_label_max_length_ = 0;

FML_DISALLOW_COPY_AND_ASSIGN(ProcTableGLES);
Expand Down
11 changes: 11 additions & 0 deletions impeller/renderer/backend/gles/texture_gles.cc
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,18 @@ TextureGLES::TextureGLES(std::shared_ptr<ReactorGLES> reactor,
type_(GetTextureTypeFromDescriptor(GetTextureDescriptor())),
handle_(reactor_->CreateHandle(ToHandleType(type_))),
is_wrapped_(is_wrapped) {
// Ensure the texture descriptor itself is valid.
if (!GetTextureDescriptor().IsValid()) {
VALIDATION_LOG << "Invalid texture descriptor.";
return;
}
// Ensure the texture doesn't exceed device capabilities.
const auto tex_size = GetTextureDescriptor().size;
const auto max_size =
reactor_->GetProcTable().GetCapabilities()->max_texture_size;
if (tex_size.Max(max_size) != max_size) {
VALIDATION_LOG << "Texture of size " << tex_size
<< " would exceed max supported size of " << max_size << ".";
return;
}
is_valid_ = true;
Expand Down

0 comments on commit bdb713c

Please sign in to comment.