| Index: gpu/command_buffer/service/texture_manager.h
 | 
| diff --git a/gpu/command_buffer/service/texture_manager.h b/gpu/command_buffer/service/texture_manager.h
 | 
| index 2dd6af2dfa8ce3eeceede19f2dbd00eaeb5f6e37..af5eb0ccf2209973f869c27ca023ea9965f3edba 100644
 | 
| --- a/gpu/command_buffer/service/texture_manager.h
 | 
| +++ b/gpu/command_buffer/service/texture_manager.h
 | 
| @@ -6,6 +6,7 @@
 | 
|  #define GPU_COMMAND_BUFFER_SERVICE_TEXTURE_MANAGER_H_
 | 
|  
 | 
|  #include <list>
 | 
| +#include <set>
 | 
|  #include <string>
 | 
|  #include <vector>
 | 
|  #include "base/basictypes.h"
 | 
| @@ -25,13 +26,17 @@ class GLES2Decoder;
 | 
|  class Display;
 | 
|  class ErrorState;
 | 
|  class FeatureInfo;
 | 
| +class FramebufferManager;
 | 
|  class TextureDefinition;
 | 
|  class TextureManager;
 | 
| +class TextureRef;
 | 
|  
 | 
|  // Info about Textures currently in the system.
 | 
| -class GPU_EXPORT Texture : public base::RefCounted<Texture> {
 | 
| +// This class wraps a real GL texture, keeping track of its meta-data. It is
 | 
| +// jointly owned by possibly multiple TextureRef.
 | 
| +class GPU_EXPORT Texture {
 | 
|   public:
 | 
| -  Texture(TextureManager* manager, GLuint service_id);
 | 
| +  explicit Texture(GLuint service_id);
 | 
|  
 | 
|    GLenum min_filter() const {
 | 
|      return min_filter_;
 | 
| @@ -102,10 +107,6 @@ class GPU_EXPORT Texture : public base::RefCounted<Texture> {
 | 
|    // does not exist.
 | 
|    gfx::GLImage* GetLevelImage(GLint target, GLint level) const;
 | 
|  
 | 
| -  bool IsDeleted() const {
 | 
| -    return deleted_;
 | 
| -  }
 | 
| -
 | 
|    // Returns true of the given dimensions are inside the dimensions of the
 | 
|    // level and if the format and type match the level.
 | 
|    bool ValidForTexture(
 | 
| @@ -119,7 +120,7 @@ class GPU_EXPORT Texture : public base::RefCounted<Texture> {
 | 
|        GLenum type) const;
 | 
|  
 | 
|    bool IsValid() const {
 | 
| -    return target() && !IsDeleted();
 | 
| +    return !!target();
 | 
|    }
 | 
|  
 | 
|    void SetNotOwned() {
 | 
| @@ -143,15 +144,13 @@ class GPU_EXPORT Texture : public base::RefCounted<Texture> {
 | 
|      return stream_texture_;
 | 
|    }
 | 
|  
 | 
| -  gpu::AsyncPixelTransferState* GetAsyncTransferState() const {
 | 
| -    return async_transfer_state_.get();
 | 
| -  }
 | 
| -  void SetAsyncTransferState(scoped_ptr<gpu::AsyncPixelTransferState> state) {
 | 
| -    async_transfer_state_ = state.Pass();
 | 
| -  }
 | 
| +  // Gets the async transfer state for this texture. Note: the transfer state is
 | 
| +  // owned by a single TextureRef.
 | 
| +  AsyncPixelTransferState* GetAsyncTransferState() const;
 | 
| +
 | 
|    bool AsyncTransferIsInProgress() {
 | 
| -    return async_transfer_state_ &&
 | 
| -        async_transfer_state_->TransferIsInProgress();
 | 
| +    AsyncPixelTransferState* state = GetAsyncTransferState();
 | 
| +    return state && state->TransferIsInProgress();
 | 
|    }
 | 
|  
 | 
|    void SetImmutable(bool immutable) {
 | 
| @@ -172,10 +171,25 @@ class GPU_EXPORT Texture : public base::RefCounted<Texture> {
 | 
|  
 | 
|   private:
 | 
|    friend class TextureManager;
 | 
| +  friend class TextureRef;
 | 
|    friend class TextureTestHelper;
 | 
| -  friend class base::RefCounted<Texture>;
 | 
|  
 | 
|    ~Texture();
 | 
| +  void AddTextureRef(TextureRef* ref);
 | 
| +  void RemoveTextureRef(TextureRef* ref, bool have_context);
 | 
| +  MemoryTypeTracker* GetMemTracker();
 | 
| +
 | 
| +  // Condition on which this texture is renderable. Can be ONLY_IF_NPOT if it
 | 
| +  // depends on context support for non-power-of-two textures (i.e. will be
 | 
| +  // renderable if NPOT support is in the context, otherwise not, e.g. texture
 | 
| +  // with a NPOT level). ALWAYS means it doesn't depend on context features
 | 
| +  // (e.g. complete POT), NEVER means it's not renderable regardless (e.g.
 | 
| +  // incomplete).
 | 
| +  enum CanRenderCondition {
 | 
| +    CAN_RENDER_ALWAYS,
 | 
| +    CAN_RENDER_NEVER,
 | 
| +    CAN_RENDER_ONLY_IF_NPOT
 | 
| +  };
 | 
|  
 | 
|    struct LevelInfo {
 | 
|      LevelInfo();
 | 
| @@ -230,6 +244,7 @@ class GPU_EXPORT Texture : public base::RefCounted<Texture> {
 | 
|  
 | 
|    void SetStreamTexture(bool stream_texture) {
 | 
|      stream_texture_ = stream_texture;
 | 
| +    UpdateCanRenderCondition();
 | 
|    }
 | 
|  
 | 
|    // Marks a particular level as cleared or uncleared.
 | 
| @@ -255,10 +270,6 @@ class GPU_EXPORT Texture : public base::RefCounted<Texture> {
 | 
|    // Makes each of the mip levels as though they were generated.
 | 
|    bool MarkMipmapsGenerated(const FeatureInfo* feature_info);
 | 
|  
 | 
| -  void MarkAsDeleted() {
 | 
| -    deleted_ = true;
 | 
| -  }
 | 
| -
 | 
|    bool NeedsMips() const {
 | 
|      return min_filter_ != GL_NEAREST && min_filter_ != GL_LINEAR;
 | 
|    }
 | 
| @@ -293,18 +304,39 @@ class GPU_EXPORT Texture : public base::RefCounted<Texture> {
 | 
|        const FeatureInfo* feature_info,
 | 
|        GLenum target, GLint level, std::string* signature) const;
 | 
|  
 | 
| +  // Updates the unsafe textures count in all the managers referencing this
 | 
| +  // texture.
 | 
| +  void UpdateSafeToRenderFrom(bool cleared);
 | 
| +
 | 
| +  // Updates the uncleared mip count in all the managers referencing this
 | 
| +  // texture.
 | 
| +  void UpdateMipCleared(LevelInfo* info, bool cleared);
 | 
| +
 | 
| +  // Computes the CanRenderCondition flag.
 | 
| +  CanRenderCondition GetCanRenderCondition() const;
 | 
| +
 | 
| +  // Updates the unrenderable texture count in all the managers referencing this
 | 
| +  // texture.
 | 
| +  void UpdateCanRenderCondition();
 | 
| +
 | 
| +  // Increment the framebuffer state change count in all the managers
 | 
| +  // referencing this texture.
 | 
| +  void IncAllFramebufferStateChangeCount();
 | 
| +
 | 
|    // Info about each face and level of texture.
 | 
|    std::vector<std::vector<LevelInfo> > level_infos_;
 | 
|  
 | 
| -  // The texture manager that manages this Texture.
 | 
| -  TextureManager* manager_;
 | 
| +  // The texture refs that point to this Texture.
 | 
| +  typedef std::set<TextureRef*> RefSet;
 | 
| +  RefSet refs_;
 | 
| +
 | 
| +  // The single TextureRef that accounts for memory for this texture. Must be
 | 
| +  // one of refs_.
 | 
| +  TextureRef* memory_tracking_ref_;
 | 
|  
 | 
|    // The id of the texure
 | 
|    GLuint service_id_;
 | 
|  
 | 
| -  // Whether this texture has been deleted.
 | 
| -  bool deleted_;
 | 
| -
 | 
|    // Whether all renderable mips of this texture have been cleared.
 | 
|    bool cleared_;
 | 
|  
 | 
| @@ -346,9 +378,6 @@ class GPU_EXPORT Texture : public base::RefCounted<Texture> {
 | 
|    // Whether this is a special streaming texture.
 | 
|    bool stream_texture_;
 | 
|  
 | 
| -  // State to facilitate async transfers on this texture.
 | 
| -  scoped_ptr<gpu::AsyncPixelTransferState> async_transfer_state_;
 | 
| -
 | 
|    // Whether the texture is immutable and no further changes to the format
 | 
|    // or dimensions of the texture object can be made.
 | 
|    bool immutable_;
 | 
| @@ -356,9 +385,55 @@ class GPU_EXPORT Texture : public base::RefCounted<Texture> {
 | 
|    // Size in bytes this texture is assumed to take in memory.
 | 
|    uint32 estimated_size_;
 | 
|  
 | 
| +  // Cache of the computed CanRenderCondition flag.
 | 
| +  CanRenderCondition can_render_condition_;
 | 
| +
 | 
|    DISALLOW_COPY_AND_ASSIGN(Texture);
 | 
|  };
 | 
|  
 | 
| +// This class represents a texture in a client context group. It's mostly 1:1
 | 
| +// with a client id, though it can outlive the client id if it's still bound to
 | 
| +// a FBO or another context when destroyed.
 | 
| +// Multiple TextureRef can point to the same texture with cross-context sharing.
 | 
| +class GPU_EXPORT TextureRef : public base::RefCounted<TextureRef> {
 | 
| + public:
 | 
| +  TextureRef(TextureManager* manager, Texture* texture);
 | 
| +  static scoped_refptr<TextureRef> Create(TextureManager* manager,
 | 
| +                                          GLuint service_id);
 | 
| +  const Texture* texture() const { return texture_; }
 | 
| +  Texture* texture() { return texture_; }
 | 
| +  GLuint service_id() const { return texture_->service_id(); }
 | 
| +
 | 
| +  // Sets the async transfer state for this texture. Only a single TextureRef
 | 
| +  // can set this on a given texture at any time.
 | 
| +  // NOTE: this should be per-context rather than per-texture. crbug.com/240504
 | 
| +  void SetAsyncTransferState(
 | 
| +      scoped_ptr<AsyncPixelTransferState> state) {
 | 
| +    DCHECK(!state || !texture_->GetAsyncTransferState());
 | 
| +    async_transfer_state_ = state.Pass();
 | 
| +  }
 | 
| +
 | 
| + private:
 | 
| +  friend class base::RefCounted<TextureRef>;
 | 
| +  friend class Texture;
 | 
| +  friend class TextureManager;
 | 
| +
 | 
| +  ~TextureRef();
 | 
| +  const TextureManager* manager() const { return manager_; }
 | 
| +  TextureManager* manager() { return manager_; }
 | 
| +  AsyncPixelTransferState* async_transfer_state() const {
 | 
| +    return async_transfer_state_.get();
 | 
| +  }
 | 
| +
 | 
| +  TextureManager* manager_;
 | 
| +  Texture* texture_;
 | 
| +
 | 
| +  // State to facilitate async transfers on this texture.
 | 
| +  scoped_ptr<AsyncPixelTransferState> async_transfer_state_;
 | 
| +
 | 
| +  DISALLOW_COPY_AND_ASSIGN(TextureRef);
 | 
| +};
 | 
| +
 | 
|  // This class keeps track of the textures and their sizes so we can do NPOT and
 | 
|  // texture complete checking.
 | 
|  //
 | 
| @@ -380,6 +455,10 @@ class GPU_EXPORT TextureManager {
 | 
|                   GLsizei max_cube_map_texture_size);
 | 
|    ~TextureManager();
 | 
|  
 | 
| +  void set_framebuffer_manager(FramebufferManager* manager) {
 | 
| +    framebuffer_manager_ = manager;
 | 
| +  }
 | 
| +
 | 
|    // Init the texture manager.
 | 
|    bool Initialize();
 | 
|  
 | 
| @@ -420,13 +499,13 @@ class GPU_EXPORT TextureManager {
 | 
|  
 | 
|    // True if this texture meets all the GLES2 criteria for rendering.
 | 
|    // See section 3.8.2 of the GLES2 spec.
 | 
| -  bool CanRender(const Texture* texture) const {
 | 
| -    return texture->CanRender(feature_info_);
 | 
| +  bool CanRender(const TextureRef* ref) const {
 | 
| +    return ref->texture()->CanRender(feature_info_);
 | 
|    }
 | 
|  
 | 
|    // Returns true if mipmaps can be generated by GL.
 | 
| -  bool CanGenerateMipmaps(const Texture* texture) const {
 | 
| -    return texture->CanGenerateMipmaps(feature_info_);
 | 
| +  bool CanGenerateMipmaps(const TextureRef* ref) const {
 | 
| +    return ref->texture()->CanGenerateMipmaps(feature_info_);
 | 
|    }
 | 
|  
 | 
|    // Sets the Texture's target
 | 
| @@ -434,15 +513,15 @@ class GPU_EXPORT TextureManager {
 | 
|    //   target: GL_TEXTURE_2D or GL_TEXTURE_CUBE_MAP
 | 
|    //   max_levels: The maximum levels this type of target can have.
 | 
|    void SetTarget(
 | 
| -      Texture* texture,
 | 
| +      TextureRef* ref,
 | 
|        GLenum target);
 | 
|  
 | 
|    // Marks a texture as a stream texture.
 | 
| -  void SetStreamTexture(Texture* texture, bool stream_texture);
 | 
| +  void SetStreamTexture(TextureRef* ref, bool stream_texture);
 | 
|  
 | 
|    // Set the info for a particular level in a TexureInfo.
 | 
|    void SetLevelInfo(
 | 
| -      Texture* texture,
 | 
| +      TextureRef* ref,
 | 
|        GLenum target,
 | 
|        GLint level,
 | 
|        GLenum internal_format,
 | 
| @@ -455,27 +534,27 @@ class GPU_EXPORT TextureManager {
 | 
|        bool cleared);
 | 
|  
 | 
|    // Adapter to call above function.
 | 
| -  void SetLevelInfoFromParams(Texture* texture,
 | 
| +  void SetLevelInfoFromParams(TextureRef* ref,
 | 
|                                const gpu::AsyncTexImage2DParams& params) {
 | 
|      SetLevelInfo(
 | 
| -        texture, params.target, params.level, params.internal_format,
 | 
| +        ref, params.target, params.level, params.internal_format,
 | 
|          params.width, params.height, 1 /* depth */,
 | 
|          params.border, params.format,
 | 
|          params.type, true /* cleared */ );
 | 
|    }
 | 
|  
 | 
|    // Save the texture definition and leave it undefined.
 | 
| -  TextureDefinition* Save(Texture* texture);
 | 
| +  TextureDefinition* Save(TextureRef* ref);
 | 
|  
 | 
|    // Redefine all the levels from the texture definition.
 | 
|    bool Restore(
 | 
|        const char* function_name,
 | 
|        GLES2Decoder* decoder,
 | 
| -      Texture* texture,
 | 
| +      TextureRef* ref,
 | 
|        TextureDefinition* definition);
 | 
|  
 | 
|    // Sets a mip as cleared.
 | 
| -  void SetLevelCleared(Texture* texture, GLenum target,
 | 
| +  void SetLevelCleared(TextureRef* ref, GLenum target,
 | 
|                         GLint level, bool cleared);
 | 
|  
 | 
|    // Sets a texture parameter of a Texture
 | 
| @@ -483,24 +562,24 @@ class GPU_EXPORT TextureManager {
 | 
|    // TODO(gman): Expand to SetParameteri,f,iv,fv
 | 
|    void SetParameter(
 | 
|        const char* function_name, ErrorState* error_state,
 | 
| -      Texture* texture, GLenum pname, GLint param);
 | 
| +      TextureRef* ref, GLenum pname, GLint param);
 | 
|  
 | 
|    // Makes each of the mip levels as though they were generated.
 | 
|    // Returns false if that's not allowed for the given texture.
 | 
| -  bool MarkMipmapsGenerated(Texture* texture);
 | 
| +  bool MarkMipmapsGenerated(TextureRef* ref);
 | 
|  
 | 
|    // Clears any uncleared renderable levels.
 | 
| -  bool ClearRenderableLevels(GLES2Decoder* decoder, Texture* texture);
 | 
| +  bool ClearRenderableLevels(GLES2Decoder* decoder, TextureRef* ref);
 | 
|  
 | 
|    // Clear a specific level.
 | 
|    bool ClearTextureLevel(
 | 
| -      GLES2Decoder* decoder,Texture* texture, GLenum target, GLint level);
 | 
| +      GLES2Decoder* decoder, TextureRef* ref, GLenum target, GLint level);
 | 
|  
 | 
|    // Creates a new texture info.
 | 
| -  Texture* CreateTexture(GLuint client_id, GLuint service_id);
 | 
| +  TextureRef* CreateTexture(GLuint client_id, GLuint service_id);
 | 
|  
 | 
|    // Gets the texture info for the given texture.
 | 
| -  Texture* GetTexture(GLuint client_id) const;
 | 
| +  TextureRef* GetTexture(GLuint client_id) const;
 | 
|  
 | 
|    // Removes a texture info.
 | 
|    void RemoveTexture(GLuint client_id);
 | 
| @@ -508,7 +587,7 @@ class GPU_EXPORT TextureManager {
 | 
|    // Gets a client id for a given service id.
 | 
|    bool GetClientId(GLuint service_id, GLuint* client_id) const;
 | 
|  
 | 
| -  Texture* GetDefaultTextureInfo(GLenum target) {
 | 
| +  TextureRef* GetDefaultTextureInfo(GLenum target) {
 | 
|      switch (target) {
 | 
|        case GL_TEXTURE_2D:
 | 
|          return default_textures_[kTexture2D];
 | 
| @@ -559,27 +638,34 @@ class GPU_EXPORT TextureManager {
 | 
|    }
 | 
|  
 | 
|    void SetLevelImage(
 | 
| -      Texture* texture,
 | 
| +      TextureRef* ref,
 | 
|        GLenum target,
 | 
|        GLint level,
 | 
|        gfx::GLImage* image);
 | 
|  
 | 
|    void AddToSignature(
 | 
| -      Texture* texture,
 | 
| +      TextureRef* ref,
 | 
|        GLenum target,
 | 
|        GLint level,
 | 
|        std::string* signature) const;
 | 
|  
 | 
|   private:
 | 
|    friend class Texture;
 | 
| +  friend class TextureRef;
 | 
|  
 | 
|    // Helper for Initialize().
 | 
| -  scoped_refptr<Texture> CreateDefaultAndBlackTextures(
 | 
| +  scoped_refptr<TextureRef> CreateDefaultAndBlackTextures(
 | 
|        GLenum target,
 | 
|        GLuint* black_texture);
 | 
|  
 | 
| -  void StartTracking(Texture* texture);
 | 
| -  void StopTracking(Texture* texture);
 | 
| +  void StartTracking(TextureRef* texture);
 | 
| +  void StopTracking(TextureRef* texture);
 | 
| +
 | 
| +  void UpdateSafeToRenderFrom(int delta);
 | 
| +  void UpdateUnclearedMips(int delta);
 | 
| +  void UpdateCanRenderCondition(Texture::CanRenderCondition old_condition,
 | 
| +                                Texture::CanRenderCondition new_condition);
 | 
| +  void IncFramebufferStateChangeCount();
 | 
|  
 | 
|    MemoryTypeTracker* GetMemTracker(GLenum texture_pool);
 | 
|    scoped_ptr<MemoryTypeTracker> memory_tracker_managed_;
 | 
| @@ -587,8 +673,10 @@ class GPU_EXPORT TextureManager {
 | 
|  
 | 
|    scoped_refptr<FeatureInfo> feature_info_;
 | 
|  
 | 
| +  FramebufferManager* framebuffer_manager_;
 | 
| +
 | 
|    // Info for each texture in the system.
 | 
| -  typedef base::hash_map<GLuint, scoped_refptr<Texture> > TextureMap;
 | 
| +  typedef base::hash_map<GLuint, scoped_refptr<TextureRef> > TextureMap;
 | 
|    TextureMap textures_;
 | 
|  
 | 
|    GLsizei max_texture_size_;
 | 
| @@ -612,7 +700,7 @@ class GPU_EXPORT TextureManager {
 | 
|    GLuint black_texture_ids_[kNumDefaultTextures];
 | 
|  
 | 
|    // The default textures for each target (texture name = 0)
 | 
| -  scoped_refptr<Texture> default_textures_[kNumDefaultTextures];
 | 
| +  scoped_refptr<TextureRef> default_textures_[kNumDefaultTextures];
 | 
|  
 | 
|    DISALLOW_COPY_AND_ASSIGN(TextureManager);
 | 
|  };
 | 
| 
 |