| Index: gpu/command_buffer/service/texture_manager.cc
|
| diff --git a/gpu/command_buffer/service/texture_manager.cc b/gpu/command_buffer/service/texture_manager.cc
|
| index b1bbe1242d4dd1ceeb344d81e24324a077ae0da8..f4bf8e24d10eef6ed00da81fdd22cc1fd0a5bcac 100644
|
| --- a/gpu/command_buffer/service/texture_manager.cc
|
| +++ b/gpu/command_buffer/service/texture_manager.cc
|
| @@ -10,7 +10,6 @@
|
| #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
|
| #include "gpu/command_buffer/service/mailbox_manager.h"
|
| #include "gpu/command_buffer/service/memory_tracking.h"
|
| -#include "gpu/command_buffer/service/texture_definition.h"
|
|
|
| namespace gpu {
|
| namespace gles2 {
|
| @@ -108,13 +107,20 @@ Texture::Texture(TextureManager* manager, GLuint service_id)
|
| owned_(true),
|
| stream_texture_(false),
|
| immutable_(false),
|
| - estimated_size_(0) {
|
| + estimated_size_(0),
|
| + shared_texture_(NULL) {
|
| if (manager_) {
|
| manager_->StartTracking(this);
|
| }
|
| }
|
|
|
| Texture::~Texture() {
|
| + if (shared_texture_) {
|
| + bool have_context = manager_ && manager_->have_context_;
|
| + owned_ = shared_texture_->service_id() != service_id();
|
| + StopUsingSharedTexture(have_context);
|
| + }
|
| +
|
| if (manager_) {
|
| if (owned_ && manager_->have_context_) {
|
| GLuint id = service_id();
|
| @@ -694,6 +700,19 @@ gfx::GLImage* Texture::GetLevelImage(
|
| return 0;
|
| }
|
|
|
| +
|
| +void Texture::StartUsingSharedTexture(TextureDefinition* definition) {
|
| + shared_texture_ = definition;
|
| + TextureDefinition::Client::StartUsingSharedTexture(definition);
|
| +}
|
| +
|
| +bool Texture::StopUsingSharedTexture(bool have_context) {
|
| + bool was_deleted = TextureDefinition::Client::StopUsingSharedTexture(
|
| + shared_texture_, have_context);
|
| + shared_texture_ = NULL;
|
| + return was_deleted;
|
| +}
|
| +
|
| TextureManager::TextureManager(
|
| MemoryTracker* memory_tracker,
|
| FeatureInfo* feature_info,
|
| @@ -933,6 +952,11 @@ void TextureManager::SetLevelInfo(
|
| TextureDefinition* TextureManager::Save(Texture* texture) {
|
| DCHECK(texture->owned_);
|
|
|
| + // Fail if we are not the current owner of the shared texture.
|
| + if (texture->shared_texture_ &&
|
| + texture->shared_texture_->service_id() != texture->service_id())
|
| + return NULL;
|
| +
|
| if (texture->IsAttachedToFramebuffer())
|
| return NULL;
|
|
|
| @@ -976,17 +1000,21 @@ TextureDefinition* TextureManager::Save(Texture* texture) {
|
| GLuint new_service_id = 0;
|
| glGenTextures(1, &new_service_id);
|
| texture->SetServiceId(new_service_id);
|
| - texture->SetImmutable(false);
|
| -
|
| - return new TextureDefinition(texture->target(),
|
| - old_service_id,
|
| - texture->min_filter(),
|
| - texture->mag_filter(),
|
| - texture->wrap_s(),
|
| - texture->wrap_t(),
|
| - texture->usage(),
|
| - immutable,
|
| - level_infos);
|
| + texture->SetImmutable(true);
|
| +
|
| + if (!texture->shared_texture_) {
|
| + texture->StartUsingSharedTexture(
|
| + new TextureDefinition(texture->target(),
|
| + old_service_id,
|
| + texture->min_filter(),
|
| + texture->mag_filter(),
|
| + texture->wrap_s(),
|
| + texture->wrap_t(),
|
| + texture->usage(),
|
| + immutable,
|
| + level_infos));
|
| + }
|
| + return texture->shared_texture_;
|
| }
|
|
|
| bool TextureManager::Restore(
|
| @@ -996,8 +1024,6 @@ bool TextureManager::Restore(
|
| TextureDefinition* definition) {
|
| DCHECK(texture->owned_);
|
|
|
| - scoped_ptr<TextureDefinition> scoped_definition(definition);
|
| -
|
| if (texture->IsAttachedToFramebuffer())
|
| return false;
|
|
|
| @@ -1036,8 +1062,26 @@ bool TextureManager::Restore(
|
| }
|
|
|
| GLuint old_service_id = texture->service_id();
|
| - glDeleteTextures(1, &old_service_id);
|
| - texture->SetServiceId(definition->ReleaseServiceId());
|
| +
|
| + // We don't allow real sharing (yet), so we can't already be using the same
|
| + // texture.
|
| + DCHECK(definition->service_id() != old_service_id);
|
| +
|
| + if (texture->shared_texture_ && texture->shared_texture_ != definition) {
|
| + // We were already referencing a texture, and it's different from the one we
|
| + // are consuming now.
|
| + bool owned = texture->shared_texture_->service_id() != old_service_id;
|
| + if (owned)
|
| + glDeleteTextures(1, &old_service_id);
|
| + texture->StopUsingSharedTexture(true);
|
| + } else {
|
| + glDeleteTextures(1, &old_service_id);
|
| + }
|
| +
|
| + if (!texture->shared_texture_)
|
| + texture->StartUsingSharedTexture(definition);
|
| +
|
| + texture->SetServiceId(definition->service_id());
|
| glBindTexture(texture->target(), texture->service_id());
|
| texture->SetImmutable(definition->immutable());
|
| SetParameter(function_name, decoder, texture, GL_TEXTURE_MIN_FILTER,
|
|
|