Commit fd4fc476 authored by Geoff Lang's avatar Geoff Lang Committed by Commit Bot

Use internal enums and a flat array for bound texture tracking.

Storing the bound textures in flat arrays significantly improves the
performance of binding textures in the passthrough command decoder.

BUG=angleproject:2188

Cq-Include-Trybots: master.tryserver.chromium.android:android_optional_gpu_tests_rel;master.tryserver.chromium.linux:linux_optional_gpu_tests_rel;master.tryserver.chromium.mac:mac_optional_gpu_tests_rel;master.tryserver.chromium.win:win_optional_gpu_tests_rel
Change-Id: Ibb9dca361a2d598aece5b9ed7ed2e373ae9b7183
Reviewed-on: https://chromium-review.googlesource.com/811765
Commit-Queue: Geoff Lang <geofflang@chromium.org>
Reviewed-by: default avatarAntoine Labour <piman@chromium.org>
Cr-Commit-Position: refs/heads/master@{#527091}
parent c9de5405
...@@ -691,24 +691,15 @@ gpu::ContextResult GLES2DecoderPassthroughImpl::Initialize( ...@@ -691,24 +691,15 @@ gpu::ContextResult GLES2DecoderPassthroughImpl::Initialize(
GLint num_texture_units = 0; GLint num_texture_units = 0;
api()->glGetIntegervFn(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, api()->glGetIntegervFn(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS,
&num_texture_units); &num_texture_units);
if (num_texture_units > static_cast<GLint>(kMaxTextureUnits)) {
Destroy(true);
LOG(ERROR) << "kMaxTextureUnits (" << kMaxTextureUnits
<< ") must be at least GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS ("
<< num_texture_units << ").";
return gpu::ContextResult::kFatalFailure;
}
active_texture_unit_ = 0; active_texture_unit_ = 0;
bound_textures_[GL_TEXTURE_2D].resize(num_texture_units);
bound_textures_[GL_TEXTURE_CUBE_MAP].resize(num_texture_units);
if (feature_info_->gl_version_info().IsAtLeastGLES(3, 0)) {
bound_textures_[GL_TEXTURE_2D_ARRAY].resize(num_texture_units);
bound_textures_[GL_TEXTURE_3D].resize(num_texture_units);
}
if (feature_info_->gl_version_info().IsAtLeastGLES(3, 1)) {
bound_textures_[GL_TEXTURE_2D_MULTISAMPLE].resize(num_texture_units);
}
if (feature_info_->feature_flags().oes_egl_image_external ||
feature_info_->feature_flags().nv_egl_stream_consumer_external) {
bound_textures_[GL_TEXTURE_EXTERNAL_OES].resize(num_texture_units);
}
if (feature_info_->feature_flags().arb_texture_rectangle) {
bound_textures_[GL_TEXTURE_RECTANGLE_ARB].resize(num_texture_units);
}
// Initialize the tracked buffer bindings // Initialize the tracked buffer bindings
bound_buffers_[GL_ARRAY_BUFFER] = 0; bound_buffers_[GL_ARRAY_BUFFER] = 0;
...@@ -847,16 +838,14 @@ void GLES2DecoderPassthroughImpl::Destroy(bool have_context) { ...@@ -847,16 +838,14 @@ void GLES2DecoderPassthroughImpl::Destroy(bool have_context) {
pending_read_pixels_.clear(); pending_read_pixels_.clear();
} }
if (!have_context) { for (auto& bound_texture_type : bound_textures_) {
for (const auto& bound_texture_type : bound_textures_) { for (auto& bound_texture : bound_texture_type) {
for (const auto& bound_texture : bound_texture_type.second) { if (!have_context && bound_texture.texture) {
if (bound_texture.texture) { bound_texture.texture->MarkContextLost();
bound_texture.texture->MarkContextLost();
}
} }
bound_texture.texture = nullptr;
} }
} }
bound_textures_.clear();
DeleteServiceObjects(&framebuffer_id_map_, have_context, DeleteServiceObjects(&framebuffer_id_map_, have_context,
[this](GLuint client_id, GLuint framebuffer) { [this](GLuint client_id, GLuint framebuffer) {
...@@ -1423,7 +1412,9 @@ void GLES2DecoderPassthroughImpl::BindImage(uint32_t client_texture_id, ...@@ -1423,7 +1412,9 @@ void GLES2DecoderPassthroughImpl::BindImage(uint32_t client_texture_id,
// Binding an image to a texture requires that the texture is currently // Binding an image to a texture requires that the texture is currently
// bound. // bound.
scoped_refptr<TexturePassthrough> current_texture = scoped_refptr<TexturePassthrough> current_texture =
bound_textures_[bind_target][active_texture_unit_].texture; bound_textures_[static_cast<size_t>(GLenumToTextureTarget(bind_target))]
[active_texture_unit_]
.texture;
bool bind_new_texture = current_texture != passthrough_texture; bool bind_new_texture = current_texture != passthrough_texture;
if (bind_new_texture) { if (bind_new_texture) {
api()->glBindTextureFn(bind_target, passthrough_texture->service_id()); api()->glBindTextureFn(bind_target, passthrough_texture->service_id());
...@@ -1928,7 +1919,8 @@ void GLES2DecoderPassthroughImpl::UpdateTextureBinding( ...@@ -1928,7 +1919,8 @@ void GLES2DecoderPassthroughImpl::UpdateTextureBinding(
TexturePassthrough* texture) { TexturePassthrough* texture) {
GLuint texture_service_id = texture ? texture->service_id() : 0; GLuint texture_service_id = texture ? texture->service_id() : 0;
size_t cur_texture_unit = active_texture_unit_; size_t cur_texture_unit = active_texture_unit_;
auto& target_bound_textures = bound_textures_.at(target); auto& target_bound_textures =
bound_textures_[static_cast<size_t>(GLenumToTextureTarget(target))];
for (size_t bound_texture_index = 0; for (size_t bound_texture_index = 0;
bound_texture_index < target_bound_textures.size(); bound_texture_index < target_bound_textures.size();
bound_texture_index++) { bound_texture_index++) {
...@@ -1969,7 +1961,8 @@ error::Error GLES2DecoderPassthroughImpl::BindTexImage2DCHROMIUMImpl( ...@@ -1969,7 +1961,8 @@ error::Error GLES2DecoderPassthroughImpl::BindTexImage2DCHROMIUMImpl(
} }
const BoundTexture& bound_texture = const BoundTexture& bound_texture =
bound_textures_[GL_TEXTURE_2D][active_texture_unit_]; bound_textures_[static_cast<size_t>(TextureTarget::k2D)]
[active_texture_unit_];
if (bound_texture.texture == nullptr) { if (bound_texture.texture == nullptr) {
InsertError(GL_INVALID_OPERATION, "No texture bound"); InsertError(GL_INVALID_OPERATION, "No texture bound");
return error::kNoError; return error::kNoError;
...@@ -2025,6 +2018,29 @@ bool GLES2DecoderPassthroughImpl::IsEmulatedFramebufferBound( ...@@ -2025,6 +2018,29 @@ bool GLES2DecoderPassthroughImpl::IsEmulatedFramebufferBound(
return false; return false;
} }
// static
GLES2DecoderPassthroughImpl::TextureTarget
GLES2DecoderPassthroughImpl::GLenumToTextureTarget(GLenum target) {
switch (target) {
case GL_TEXTURE_2D:
return TextureTarget::k2D;
case GL_TEXTURE_CUBE_MAP:
return TextureTarget::kCubeMap;
case GL_TEXTURE_2D_ARRAY:
return TextureTarget::k2DArray;
case GL_TEXTURE_3D:
return TextureTarget::k3D;
case GL_TEXTURE_2D_MULTISAMPLE:
return TextureTarget::k2DMultisample;
case GL_TEXTURE_EXTERNAL_OES:
return TextureTarget::kExternal;
case GL_TEXTURE_RECTANGLE_ARB:
return TextureTarget::kRectangle;
default:
return TextureTarget::kUnkown;
}
}
#define GLES2_CMD_OP(name) \ #define GLES2_CMD_OP(name) \
{ \ { \
&GLES2DecoderPassthroughImpl::Handle##name, cmds::name::kArgFlags, \ &GLES2DecoderPassthroughImpl::Handle##name, cmds::name::kArgFlags, \
......
...@@ -457,6 +457,20 @@ class GPU_EXPORT GLES2DecoderPassthroughImpl : public GLES2Decoder { ...@@ -457,6 +457,20 @@ class GPU_EXPORT GLES2DecoderPassthroughImpl : public GLES2Decoder {
// State tracking of currently bound 2D textures (client IDs) // State tracking of currently bound 2D textures (client IDs)
size_t active_texture_unit_; size_t active_texture_unit_;
enum class TextureTarget : uint8_t {
k2D = 0,
kCubeMap = 1,
k2DArray = 2,
k3D = 3,
k2DMultisample = 4,
kExternal = 5,
kRectangle = 6,
kUnkown = 7,
kCount = kUnkown,
};
static TextureTarget GLenumToTextureTarget(GLenum target);
struct BoundTexture { struct BoundTexture {
BoundTexture(); BoundTexture();
~BoundTexture(); ~BoundTexture();
...@@ -468,7 +482,14 @@ class GPU_EXPORT GLES2DecoderPassthroughImpl : public GLES2Decoder { ...@@ -468,7 +482,14 @@ class GPU_EXPORT GLES2DecoderPassthroughImpl : public GLES2Decoder {
GLuint client_id = 0; GLuint client_id = 0;
scoped_refptr<TexturePassthrough> texture; scoped_refptr<TexturePassthrough> texture;
}; };
std::unordered_map<GLenum, std::vector<BoundTexture>> bound_textures_;
// Use a limit that is at least ANGLE's IMPLEMENTATION_MAX_ACTIVE_TEXTURES
// constant
static constexpr size_t kMaxTextureUnits = 64;
static constexpr size_t kNumTextureTypes =
static_cast<size_t>(TextureTarget::kCount);
std::array<std::array<BoundTexture, kMaxTextureUnits>, kNumTextureTypes>
bound_textures_;
// State tracking of currently bound buffers // State tracking of currently bound buffers
std::unordered_map<GLenum, GLuint> bound_buffers_; std::unordered_map<GLenum, GLuint> bound_buffers_;
......
...@@ -326,6 +326,8 @@ error::Error GLES2DecoderPassthroughImpl::DoActiveTexture(GLenum texture) { ...@@ -326,6 +326,8 @@ error::Error GLES2DecoderPassthroughImpl::DoActiveTexture(GLenum texture) {
} }
active_texture_unit_ = static_cast<size_t>(texture) - GL_TEXTURE0; active_texture_unit_ = static_cast<size_t>(texture) - GL_TEXTURE0;
DCHECK(active_texture_unit_ < kMaxTextureUnits);
return error::kNoError; return error::kNoError;
} }
...@@ -461,8 +463,7 @@ error::Error GLES2DecoderPassthroughImpl::DoBindTexture(GLenum target, ...@@ -461,8 +463,7 @@ error::Error GLES2DecoderPassthroughImpl::DoBindTexture(GLenum target,
} }
// Track the currently bound textures // Track the currently bound textures
DCHECK(bound_textures_.find(target) != bound_textures_.end()); DCHECK(GLenumToTextureTarget(target) != TextureTarget::kUnkown);
DCHECK(bound_textures_[target].size() > active_texture_unit_);
scoped_refptr<TexturePassthrough> texture_passthrough = nullptr; scoped_refptr<TexturePassthrough> texture_passthrough = nullptr;
if (service_id != 0) { if (service_id != 0) {
...@@ -478,7 +479,9 @@ error::Error GLES2DecoderPassthroughImpl::DoBindTexture(GLenum target, ...@@ -478,7 +479,9 @@ error::Error GLES2DecoderPassthroughImpl::DoBindTexture(GLenum target,
} }
} }
BoundTexture* bound_texture = &bound_textures_[target][active_texture_unit_]; BoundTexture* bound_texture =
&bound_textures_[static_cast<size_t>(GLenumToTextureTarget(target))]
[active_texture_unit_];
bound_texture->client_id = texture; bound_texture->client_id = texture;
bound_texture->texture = std::move(texture_passthrough); bound_texture->texture = std::move(texture_passthrough);
...@@ -4016,7 +4019,8 @@ error::Error GLES2DecoderPassthroughImpl::DoReleaseTexImage2DCHROMIUM( ...@@ -4016,7 +4019,8 @@ error::Error GLES2DecoderPassthroughImpl::DoReleaseTexImage2DCHROMIUM(
} }
const BoundTexture& bound_texture = const BoundTexture& bound_texture =
bound_textures_[GL_TEXTURE_2D][active_texture_unit_]; bound_textures_[static_cast<size_t>(TextureTarget::k2D)]
[active_texture_unit_];
if (bound_texture.texture == nullptr) { if (bound_texture.texture == nullptr) {
InsertError(GL_INVALID_OPERATION, "No texture bound"); InsertError(GL_INVALID_OPERATION, "No texture bound");
return error::kNoError; return error::kNoError;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment