Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(393)

Unified Diff: gpu/command_buffer/service/gles2_cmd_decoder.cc

Issue 1401423003: Re-land: ui: Move GLImage::BindTexImage fallback from GLImage implementations to GLES2CmdDecoder. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: gpu/command_buffer/service/gles2_cmd_decoder.cc
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 626e362bc4dddcbe94280aa38c801eb2d15d19df..d938bc881bcc71ade359bf2787521cf177e638d2 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -1966,7 +1966,17 @@ class GLES2DecoderImpl : public GLES2Decoder,
const char* function_name, GLuint max_vertex_accessed, bool* simulated);
void RestoreStateForAttrib(GLuint attrib, bool restore_array_binding);
- // If an image is bound to texture, this will call Will/DidUseTexImage
+ // Calls WillUseTexImage or copies the image to the texture currently bound
+ // to |textarget| based on the value of |image_state|. The new image state is
+ // returned.
+ Texture::ImageState DoWillUseTexImage(GLenum textarget,
+ gfx::GLImage* image,
+ Texture::ImageState image_state);
+
+ // Calls DidUseTexImage based on the value of |image_state|.
+ void DoDidUseTexImage(gfx::GLImage* image, Texture::ImageState image_state);
+
+ // If an image is bound to texture, this will call DoWill/DidUseTexImage
// if needed.
void DoWillUseTexImageIfNeeded(Texture* texture, GLenum textarget);
void DoDidUseTexImageIfNeeded(Texture* texture, GLenum textarget);
@@ -7622,18 +7632,56 @@ void GLES2DecoderImpl::PerformanceWarning(
std::string("PERFORMANCE WARNING: ") + msg);
}
+Texture::ImageState GLES2DecoderImpl::DoWillUseTexImage(
+ GLenum textarget,
+ gfx::GLImage* image,
+ Texture::ImageState image_state) {
+ switch (image_state) {
+ case Texture::UNBOUND: {
+ bool rv = image->CopyTexImage(textarget);
+ DCHECK(rv) << "Both BindTexImage() and CopyTexImage() failed";
+ return Texture::COPIED;
Daniele Castagna 2015/10/14 18:40:35 nit: should this be UNBOUND, not that it matters.
reveman 2015/10/14 19:28:01 State should change to COPIED to prevent us from c
+ }
+ case Texture::BOUND:
+ image->WillUseTexImage();
+ return Texture::BOUND;
+ case Texture::COPIED:
+ return Texture::COPIED;
+ }
+
+ NOTREACHED();
+ return Texture::UNBOUND;
+}
+
+void GLES2DecoderImpl::DoDidUseTexImage(gfx::GLImage* image,
+ Texture::ImageState image_state) {
+ switch (image_state) {
+ case Texture::BOUND:
+ image->DidUseTexImage();
+ return;
+ case Texture::UNBOUND:
+ case Texture::COPIED:
+ return;
+ }
+
+ NOTREACHED();
+}
+
void GLES2DecoderImpl::DoWillUseTexImageIfNeeded(
Texture* texture, GLenum textarget) {
// Image is already in use if texture is attached to a framebuffer.
if (texture && !texture->IsAttachedToFramebuffer()) {
- gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
+ Texture::ImageState image_state;
+ gfx::GLImage* image = texture->GetLevelImage(textarget, 0, &image_state);
if (image) {
ScopedGLErrorSuppressor suppressor(
"GLES2DecoderImpl::DoWillUseTexImageIfNeeded",
GetErrorState());
glBindTexture(textarget, texture->service_id());
- image->WillUseTexImage();
+ Texture::ImageState new_image_state =
+ DoWillUseTexImage(textarget, image, image_state);
RestoreCurrentTextureBindings(&state_, textarget);
+ texture->SetLevelImage(textarget, 0, image, new_image_state);
}
}
}
@@ -7642,13 +7690,14 @@ void GLES2DecoderImpl::DoDidUseTexImageIfNeeded(
Texture* texture, GLenum textarget) {
// Image is still in use if texture is attached to a framebuffer.
if (texture && !texture->IsAttachedToFramebuffer()) {
- gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
+ Texture::ImageState image_state;
+ gfx::GLImage* image = texture->GetLevelImage(textarget, 0, &image_state);
if (image) {
ScopedGLErrorSuppressor suppressor(
"GLES2DecoderImpl::DoDidUseTexImageIfNeeded",
GetErrorState());
glBindTexture(textarget, texture->service_id());
- image->DidUseTexImage();
+ DoDidUseTexImage(image, image_state);
RestoreCurrentTextureBindings(&state_, textarget);
}
}
@@ -7696,13 +7745,17 @@ bool GLES2DecoderImpl::PrepareTexturesForRender() {
if (textarget != GL_TEXTURE_CUBE_MAP) {
Texture* texture = texture_ref->texture();
- gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
+ Texture::ImageState image_state;
+ gfx::GLImage* image =
+ texture->GetLevelImage(textarget, 0, &image_state);
if (image && !texture->IsAttachedToFramebuffer()) {
ScopedGLErrorSuppressor suppressor(
"GLES2DecoderImpl::PrepareTexturesForRender", GetErrorState());
textures_set = true;
glActiveTexture(GL_TEXTURE0 + texture_unit_index);
- image->WillUseTexImage();
+ Texture::ImageState new_image_state =
+ DoWillUseTexImage(textarget, image, image_state);
+ texture->SetLevelImage(textarget, 0, image, new_image_state);
continue;
}
}
@@ -7740,13 +7793,14 @@ void GLES2DecoderImpl::RestoreStateForTextures() {
if (texture_unit.bind_target != GL_TEXTURE_CUBE_MAP) {
Texture* texture = texture_ref->texture();
+ Texture::ImageState image_state;
gfx::GLImage* image =
- texture->GetLevelImage(texture_unit.bind_target, 0);
+ texture->GetLevelImage(texture_unit.bind_target, 0, &image_state);
if (image && !texture->IsAttachedToFramebuffer()) {
ScopedGLErrorSuppressor suppressor(
"GLES2DecoderImpl::RestoreStateForTextures", GetErrorState());
glActiveTexture(GL_TEXTURE0 + texture_unit_index);
- image->DidUseTexImage();
+ DoDidUseTexImage(image, image_state);
continue;
}
}
@@ -9473,9 +9527,10 @@ error::Error GLES2DecoderImpl::HandleScheduleOverlayPlaneCHROMIUM(
"unknown texture");
return error::kNoError;
}
+ Texture::ImageState image_state;
gfx::GLImage* image =
- ref->texture()->GetLevelImage(ref->texture()->target(), 0);
- if (!image) {
+ ref->texture()->GetLevelImage(ref->texture()->target(), 0, &image_state);
+ if (!image || image_state != Texture::BOUND) {
LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
"glScheduleOverlayPlaneCHROMIUM",
"unsupported texture format");
@@ -13091,7 +13146,7 @@ void GLES2DecoderImpl::DoCopyTextureCHROMIUM(
int source_width = 0;
int source_height = 0;
gfx::GLImage* image =
- source_texture->GetLevelImage(source_texture->target(), 0);
+ source_texture->GetLevelImage(source_texture->target(), 0, nullptr);
if (image) {
gfx::Size size = image->GetSize();
source_width = size.width();
@@ -13195,15 +13250,13 @@ void GLES2DecoderImpl::DoCopyTextureCHROMIUM(
ScopedModifyPixels modify(dest_texture_ref);
- // Try using GLImage::CopyTexSubImage when possible.
+ // Try using GLImage::CopyTexImage when possible.
bool unpack_premultiply_alpha_change =
(unpack_premultiply_alpha ^ unpack_unmultiply_alpha) != 0;
if (image && !unpack_flip_y && !unpack_premultiply_alpha_change) {
glBindTexture(GL_TEXTURE_2D, dest_texture->service_id());
- if (image->CopyTexSubImage(GL_TEXTURE_2D, gfx::Point(0, 0),
- gfx::Rect(0, 0, source_width, source_height))) {
+ if (image->CopyTexImage(GL_TEXTURE_2D))
return;
- }
}
DoWillUseTexImageIfNeeded(source_texture, source_texture->target());
@@ -13255,7 +13308,7 @@ void GLES2DecoderImpl::DoCopySubTextureCHROMIUM(
int source_width = 0;
int source_height = 0;
gfx::GLImage* image =
- source_texture->GetLevelImage(source_texture->target(), 0);
+ source_texture->GetLevelImage(source_texture->target(), 0, nullptr);
if (image) {
gfx::Size size = image->GetSize();
source_width = size.width();
@@ -13405,7 +13458,7 @@ void GLES2DecoderImpl::DoCompressedCopyTextureCHROMIUM(GLenum target,
int source_width = 0;
int source_height = 0;
gfx::GLImage* image =
- source_texture->GetLevelImage(source_texture->target(), 0);
+ source_texture->GetLevelImage(source_texture->target(), 0, nullptr);
if (image) {
gfx::Size size = image->GetSize();
source_width = size.width();
@@ -13523,10 +13576,8 @@ void GLES2DecoderImpl::DoCompressedCopyTextureCHROMIUM(GLenum target,
true);
}
- if (image->CopyTexSubImage(GL_TEXTURE_2D, gfx::Point(0, 0),
- gfx::Rect(0, 0, source_width, source_height))) {
+ if (image->CopyTexImage(GL_TEXTURE_2D))
return;
- }
}
TRACE_EVENT0(
@@ -13587,7 +13638,7 @@ void GLES2DecoderImpl::DoCompressedCopySubTextureCHROMIUM(GLenum target,
int source_width = 0;
int source_height = 0;
gfx::GLImage* image =
- source_texture->GetLevelImage(source_texture->target(), 0);
+ source_texture->GetLevelImage(source_texture->target(), 0, nullptr);
if (image) {
gfx::Size size = image->GetSize();
source_width = size.width();
@@ -13718,11 +13769,10 @@ void GLES2DecoderImpl::DoCompressedCopySubTextureCHROMIUM(GLenum target,
ScopedModifyPixels modify(dest_texture_ref);
// Try using GLImage::CopyTexSubImage when possible.
- if (image) {
- if (image->CopyTexSubImage(GL_TEXTURE_2D, gfx::Point(xoffset, yoffset),
- gfx::Rect(x, y, width, height))) {
- return;
- }
+ if (image &&
+ image->CopyTexSubImage(GL_TEXTURE_2D, gfx::Point(xoffset, yoffset),
+ gfx::Rect(x, y, width, height))) {
+ return;
}
TRACE_EVENT0(
@@ -14196,31 +14246,39 @@ void GLES2DecoderImpl::DoBindTexImage2DCHROMIUM(
return;
}
- gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
- if (!gl_image) {
+ gfx::GLImage* image = image_manager()->LookupImage(image_id);
+ if (!image) {
LOCAL_SET_GL_ERROR(
GL_INVALID_OPERATION,
"glBindTexImage2DCHROMIUM", "no image found with the given ID");
return;
}
+ Texture::ImageState image_state = Texture::UNBOUND;
+
{
ScopedGLErrorSuppressor suppressor(
"GLES2DecoderImpl::DoBindTexImage2DCHROMIUM", GetErrorState());
- if (!gl_image->BindTexImage(target)) {
- LOCAL_SET_GL_ERROR(
- GL_INVALID_OPERATION,
- "glBindTexImage2DCHROMIUM", "fail to bind image with the given ID");
- return;
- }
+
+ // Note: We fallback to a lazy GLImage::CopyTexImage() call in
+ // DoWillUseTexImage() when BindTexImage() fails.
+ if (image->BindTexImage(target))
+ image_state = Texture::BOUND;
+ }
+
+ // GL_TEXTURE_EXTERNAL_OES is not a supported CopyTexImage() target.
+ if (target == GL_TEXTURE_EXTERNAL_OES && image_state == Texture::UNBOUND) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_ENUM, "glBindTexImage2DCHROMIUM",
+ "invalid target");
+ return;
}
- gfx::Size size = gl_image->GetSize();
+ gfx::Size size = image->GetSize();
texture_manager()->SetLevelInfo(
- texture_ref, target, 0, gl_image->GetInternalFormat(), size.width(),
- size.height(), 1, 0, gl_image->GetInternalFormat(), GL_UNSIGNED_BYTE,
+ texture_ref, target, 0, image->GetInternalFormat(), size.width(),
+ size.height(), 1, 0, image->GetInternalFormat(), GL_UNSIGNED_BYTE,
gfx::Rect(size));
- texture_manager()->SetLevelImage(texture_ref, target, 0, gl_image);
+ texture_manager()->SetLevelImage(texture_ref, target, 0, image, image_state);
}
void GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM(
@@ -14238,27 +14296,37 @@ void GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM(
return;
}
- gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
- if (!gl_image) {
+ gfx::GLImage* image = image_manager()->LookupImage(image_id);
+ if (!image) {
LOCAL_SET_GL_ERROR(
GL_INVALID_OPERATION,
"glReleaseTexImage2DCHROMIUM", "no image found with the given ID");
return;
}
+ Texture::ImageState image_state;
+
// Do nothing when image is not currently bound.
- if (texture_ref->texture()->GetLevelImage(target, 0) != gl_image)
+ if (texture_ref->texture()->GetLevelImage(target, 0, &image_state) != image)
return;
{
ScopedGLErrorSuppressor suppressor(
"GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM", GetErrorState());
- gl_image->ReleaseTexImage(target);
+
+ if (image_state == Texture::BOUND)
+ image->ReleaseTexImage(target);
+
+ if (image_state == Texture::COPIED) {
+ // Effectively frees the texture storage without deleting the texture id.
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA,
+ GL_UNSIGNED_BYTE, nullptr);
+ }
}
texture_manager()->SetLevelInfo(
- texture_ref, target, 0, gl_image->GetInternalFormat(), 0, 0, 1, 0,
- gl_image->GetInternalFormat(), GL_UNSIGNED_BYTE, gfx::Rect());
+ texture_ref, target, 0, image->GetInternalFormat(), 0, 0, 1, 0,
+ image->GetInternalFormat(), GL_UNSIGNED_BYTE, gfx::Rect());
}
error::Error GLES2DecoderImpl::HandleTraceBeginCHROMIUM(

Powered by Google App Engine
This is Rietveld 408576698