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 4f63037c5382b9329fedffcec783b71159ddc1f3..9f66b446adf4c11f5c20045d9d0c1a5c52a2d8b0 100644 |
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc |
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc |
@@ -53,8 +53,6 @@ |
#include "gpu/command_buffer/service/shader_manager.h" |
#include "gpu/command_buffer/service/shader_translator.h" |
#include "gpu/command_buffer/service/shader_translator_cache.h" |
-#include "gpu/command_buffer/service/stream_texture.h" |
-#include "gpu/command_buffer/service/stream_texture_manager.h" |
#include "gpu/command_buffer/service/texture_manager.h" |
#include "gpu/command_buffer/service/vertex_array_manager.h" |
#include "gpu/command_buffer/service/vertex_attrib_manager.h" |
@@ -295,17 +293,17 @@ class ScopedGLErrorSuppressor { |
DISALLOW_COPY_AND_ASSIGN(ScopedGLErrorSuppressor); |
}; |
-// Temporarily changes a decoder's bound 2D texture and restore it when this |
+// Temporarily changes a decoder's bound texture and restore it when this |
// object goes out of scope. Also temporarily switches to using active texture |
// unit zero in case the client has changed that to something invalid. |
-class ScopedTexture2DBinder { |
+class ScopedTextureBinder { |
public: |
- ScopedTexture2DBinder(GLES2DecoderImpl* decoder, GLuint id); |
- ~ScopedTexture2DBinder(); |
+ ScopedTextureBinder(GLES2DecoderImpl* decoder, GLenum target, GLuint id); |
+ ~ScopedTextureBinder(); |
private: |
GLES2DecoderImpl* decoder_; |
- DISALLOW_COPY_AND_ASSIGN(ScopedTexture2DBinder); |
+ DISALLOW_COPY_AND_ASSIGN(ScopedTextureBinder); |
}; |
// Temporarily changes a decoder's bound render buffer and restore it when this |
@@ -632,7 +630,7 @@ class GLES2DecoderImpl : public GLES2Decoder { |
// Restores the current state to the user's settings. |
void RestoreCurrentFramebufferBindings(); |
void RestoreCurrentRenderbufferBindings(); |
- void RestoreCurrentTexture2DBindings(); |
+ void RestoreCurrentTextureBindings(GLenum target); |
// Sets DEPTH_TEST, STENCIL_TEST and color mask for the current framebuffer. |
void ApplyDirtyState(); |
@@ -724,10 +722,6 @@ class GLES2DecoderImpl : public GLES2Decoder { |
return group_->memory_tracker(); |
} |
- StreamTextureManager* stream_texture_manager() const { |
- return group_->stream_texture_manager(); |
- } |
- |
bool EnsureGPUMemoryAvailable(size_t estimated_size) { |
MemoryTracker* tracker = memory_tracker(); |
if (tracker) { |
@@ -1402,10 +1396,6 @@ class GLES2DecoderImpl : public GLES2Decoder { |
const char* function_name, GLuint max_vertex_accessed, bool* simulated); |
void RestoreStateForAttrib(GLuint attrib); |
- // If texture is a stream texture, this will update the stream to the newest |
- // buffer. |
- void UpdateStreamTextureIfNeeded(Texture* texture); |
- |
// Returns false if unrenderable textures were replaced. |
bool PrepareTexturesForRender(); |
void RestoreStateForNonRenderableTextures(); |
@@ -1769,22 +1759,24 @@ ScopedGLErrorSuppressor::~ScopedGLErrorSuppressor() { |
ERRORSTATE_CLEAR_REAL_GL_ERRORS(decoder_->GetErrorState(), function_name_); |
} |
-ScopedTexture2DBinder::ScopedTexture2DBinder(GLES2DecoderImpl* decoder, |
- GLuint id) |
- : decoder_(decoder) { |
+ScopedTextureBinder::ScopedTextureBinder(GLES2DecoderImpl* decoder, |
+ GLenum target, |
+ GLuint id) |
+ : decoder_(decoder), |
+ target_(target) { |
ScopedGLErrorSuppressor suppressor( |
- "ScopedTexture2DBinder::ctor", decoder_); |
+ "ScopedTextureBinder::ctor", decoder_); |
// TODO(apatrick): Check if there are any other states that need to be reset |
// before binding a new texture. |
glActiveTexture(GL_TEXTURE0); |
- glBindTexture(GL_TEXTURE_2D, id); |
+ glBindTexture(target, id); |
} |
-ScopedTexture2DBinder::~ScopedTexture2DBinder() { |
+ScopedTextureBinder::~ScopedTextureBinder() { |
ScopedGLErrorSuppressor suppressor( |
- "ScopedTexture2DBinder::dtor", decoder_); |
- decoder_->RestoreCurrentTexture2DBindings(); |
+ "ScopedTextureBinder::dtor", decoder_); |
+ decoder_->RestoreCurrentTextureBindings(target_); |
} |
ScopedRenderBufferBinder::ScopedRenderBufferBinder(GLES2DecoderImpl* decoder, |
@@ -1912,7 +1904,7 @@ void BackTexture::Create() { |
ScopedGLErrorSuppressor suppressor("BackTexture::Create", decoder_); |
Destroy(); |
glGenTextures(1, &id_); |
- ScopedTexture2DBinder binder(decoder_, id_); |
+ ScopedTextureBinder binder(decoder_, GL_TEXTURE_2D, id_); |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
@@ -1935,7 +1927,7 @@ bool BackTexture::AllocateStorage( |
const gfx::Size& size, GLenum format, bool zero) { |
DCHECK_NE(id_, 0u); |
ScopedGLErrorSuppressor suppressor("BackTexture::AllocateStorage", decoder_); |
- ScopedTexture2DBinder binder(decoder_, id_); |
+ ScopedTextureBinder binder(decoder_, GL_TEXTURE_2D, id_); |
uint32 image_size = 0; |
GLES2Util::ComputeImageDataSizes( |
size.width(), size.height(), format, GL_UNSIGNED_BYTE, 8, &image_size, |
@@ -1975,7 +1967,7 @@ bool BackTexture::AllocateStorage( |
void BackTexture::Copy(const gfx::Size& size, GLenum format) { |
DCHECK_NE(id_, 0u); |
ScopedGLErrorSuppressor suppressor("BackTexture::Copy", decoder_); |
- ScopedTexture2DBinder binder(decoder_, id_); |
+ ScopedTextureBinder binder(decoder_, GL_TEXTURE_2D, id_); |
glCopyTexImage2D(GL_TEXTURE_2D, |
0, // level |
format, |
@@ -2901,16 +2893,34 @@ void GLES2DecoderImpl::RestoreCurrentFramebufferBindings() { |
OnFboChanged(); |
} |
-void GLES2DecoderImpl::RestoreCurrentTexture2DBindings() { |
+void GLES2DecoderImpl::RestoreCurrentTextureBindings(GLenum target) { |
TextureUnit& info = state_.texture_units[0]; |
GLuint last_id; |
- if (info.bound_texture_2d.get()) { |
- last_id = info.bound_texture_2d->service_id(); |
+ scoped_refptr<TextureRef> texture_ref; |
+ switch (target) { |
+ case GL_TEXTURE_2D: |
+ texture_ref = info.bound_texture_2d; |
+ break; |
+ case GL_TEXTURE_CUBE_MAP: |
+ texture_ref = info.bound_texture_cube_map; |
+ break; |
+ case GL_TEXTURE_EXTERNAL_OES: |
+ texture_ref = info.bound_texture_external_oes; |
+ break; |
+ case GL_TEXTURE_RECTANGLE_ARB: |
+ texture_ref = info.bound_texture_rectangle_arb; |
+ break; |
+ default: |
+ NOTREACHED(); |
+ break; |
+ } |
+ if (texture_ref.get()) { |
+ last_id = texture_ref->service_id(); |
} else { |
last_id = 0; |
} |
- glBindTexture(GL_TEXTURE_2D, last_id); |
+ glBindTexture(target, last_id); |
glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit); |
} |
@@ -3882,12 +3892,6 @@ void GLES2DecoderImpl::DoBindTexture(GLenum target, GLuint client_id) { |
"glBindTexture", "texture bound to more than 1 target."); |
return; |
} |
- if (texture->IsStreamTexture() && target != GL_TEXTURE_EXTERNAL_OES) { |
- LOCAL_SET_GL_ERROR( |
- GL_INVALID_OPERATION, |
- "glBindTexture", "illegal target for stream texture."); |
- return; |
- } |
LogClientServiceForInfo(texture, client_id, "glBindTexture"); |
if (texture->target() == 0) { |
texture_manager()->SetTarget(texture_ref, target); |
@@ -5669,16 +5673,6 @@ void GLES2DecoderImpl::ForceCompileShaderIfPending(Shader* shader) { |
} |
} |
-void GLES2DecoderImpl::UpdateStreamTextureIfNeeded(Texture* texture) { |
- if (texture && texture->IsStreamTexture()) { |
- DCHECK(stream_texture_manager()); |
- StreamTexture* stream_tex = |
- stream_texture_manager()->LookupStreamTexture(texture->service_id()); |
- if (stream_tex) |
- stream_tex->Update(); |
- } |
-} |
- |
bool GLES2DecoderImpl::PrepareTexturesForRender() { |
DCHECK(state_.current_program.get()); |
bool have_unrenderable_textures = |
@@ -5700,8 +5694,12 @@ bool GLES2DecoderImpl::PrepareTexturesForRender() { |
TextureUnit& texture_unit = state_.texture_units[texture_unit_index]; |
TextureRef* texture = |
texture_unit.GetInfoForSamplerType(uniform_info->type).get(); |
- if (texture) |
- UpdateStreamTextureIfNeeded(texture->texture()); |
+ if (texture && texture->texture()) { |
+ scoped_refptr<gfx::GLImage> image = texture->texture()->GetLevelImage( |
+ texture->texture()->target(), 0); |
+ if (image.get()) |
+ image->WillUseTexImage(); |
+ } |
if (have_unrenderable_textures && |
(!texture || !texture_manager()->CanRender(texture))) { |
textures_set = true; |
@@ -9486,50 +9484,60 @@ error::Error GLES2DecoderImpl::HandleCreateStreamTextureCHROMIUM( |
} |
Texture* texture = texture_ref->texture(); |
- if (texture->IsStreamTexture()) { |
- LOCAL_SET_GL_ERROR( |
- GL_INVALID_OPERATION, |
- "glCreateStreamTextureCHROMIUM", "is already a stream texture."); |
- return error::kNoError; |
- } |
- |
if (texture->target() && texture->target() != GL_TEXTURE_EXTERNAL_OES) { |
LOCAL_SET_GL_ERROR( |
GL_INVALID_OPERATION, |
"glCreateStreamTextureCHROMIUM", |
"is already bound to incompatible target."); |
return error::kNoError; |
+ } else if (!texture->target()) { |
+ texture_manager()->SetTarget(texture_ref, GL_TEXTURE_EXTERNAL_OES); |
} |
- if (!stream_texture_manager()) |
- return error::kInvalidArguments; |
- |
- GLuint object_id = stream_texture_manager()->CreateStreamTexture( |
- texture->service_id(), client_id); |
+ scoped_refptr<gfx::GLImage> image = |
+ gfx::GLImage::CreateGLImageForStreamTexture(); |
- if (object_id) { |
- texture_manager()->SetStreamTexture(texture_ref, true); |
+ { |
+ ScopedTextureBinder binder( |
+ this, GL_TEXTURE_EXTERNAL_OES, texture->service_id()); |
+ if (!image->BindTexImage()) |
+ image = NULL; |
+ } |
+ |
+ uint32 image_id = 0; |
+ if (image) { |
+ image_id = group_->GetIdAllocator(id_namespaces::kImages)->AllocateID(); |
+ image_manager()->AddImage(image, image_id); |
+ texture_manager()->SetLevelInfo(texture_ref, |
+ GL_TEXTURE_EXTERNAL_OES, |
+ 0, |
+ GL_RGBA, |
+ 0, |
+ 0, |
+ 1, |
+ 0, |
+ GL_RGBA, |
+ GL_UNSIGNED_BYTE, |
+ true); |
+ texture_manager()->SetLevelImage( |
+ texture_ref, GL_TEXTURE_EXTERNAL_OES, 0, image); |
} else { |
LOCAL_SET_GL_ERROR( |
GL_OUT_OF_MEMORY, |
"glCreateStreamTextureCHROMIUM", "failed to create platform texture."); |
} |
- *result = object_id; |
+ *result = image_id; |
return error::kNoError; |
} |
error::Error GLES2DecoderImpl::HandleDestroyStreamTextureCHROMIUM( |
uint32 immediate_data_size, |
const cmds::DestroyStreamTextureCHROMIUM& c) { |
- GLuint client_id = c.texture; |
- TextureRef* texture_ref = texture_manager()->GetTexture(client_id); |
- if (texture_ref && texture_manager()->IsStreamTextureOwner(texture_ref)) { |
- if (!stream_texture_manager()) |
- return error::kInvalidArguments; |
- |
- stream_texture_manager()->DestroyStreamTexture(texture_ref->service_id()); |
- texture_manager()->SetStreamTexture(texture_ref, false); |
+ GLuint image_id = c.texture; |
+ if (image_id && image_manager()->LookupImage(image_id)) { |
+ image_manager()->RemoveImage(image_id); |
+ group_->GetIdAllocator(id_namespaces::kImages)->FreeID(image_id); |
} else { |
LOCAL_SET_GL_ERROR( |
GL_INVALID_VALUE, |
@@ -9740,18 +9748,16 @@ void GLES2DecoderImpl::DoCopyTextureCHROMIUM( |
} |
if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) { |
- UpdateStreamTextureIfNeeded(source_texture); |
- DCHECK(stream_texture_manager()); |
- StreamTexture* stream_tex = |
- stream_texture_manager()->LookupStreamTexture( |
- source_texture->service_id()); |
- if (!stream_tex) { |
+ scoped_refptr<gfx::GLImage> image = |
+ source_texture->GetLevelImage(GL_TEXTURE_EXTERNAL_OES, 0); |
+ if (!image) { |
LOCAL_SET_GL_ERROR( |
GL_INVALID_VALUE, |
"glCopyTextureChromium", "Stream texture lookup failed"); |
return; |
} |
- gfx::Size size = stream_tex->GetSize(); |
+ image->WillUseTexImage(); |
+ gfx::Size size = image->GetSize(); |
source_width = size.width(); |
source_height = size.height(); |
if (source_width <= 0 || source_height <= 0) { |
@@ -9796,7 +9802,7 @@ void GLES2DecoderImpl::DoCopyTextureCHROMIUM( |
0, internal_format, dest_type, NULL); |
GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM"); |
if (error != GL_NO_ERROR) { |
- RestoreCurrentTexture2DBindings(); |
+ RestoreCurrentTextureBindings(GL_TEXTURE_2D); |
return; |
} |