|  | // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #ifndef GPU_COMMAND_BUFFER_SERVICE_TEXTURE_MANAGER_H_ | 
|  | #define GPU_COMMAND_BUFFER_SERVICE_TEXTURE_MANAGER_H_ | 
|  |  | 
|  | #include <stddef.h> | 
|  | #include <stdint.h> | 
|  |  | 
|  | #include <algorithm> | 
|  | #include <list> | 
|  | #include <memory> | 
|  | #include <set> | 
|  | #include <string> | 
|  | #include <vector> | 
|  |  | 
|  | #include "base/containers/hash_tables.h" | 
|  | #include "base/macros.h" | 
|  | #include "base/memory/ref_counted.h" | 
|  | #include "gpu/command_buffer/service/feature_info.h" | 
|  | #include "gpu/command_buffer/service/gl_utils.h" | 
|  | #include "gpu/command_buffer/service/memory_tracking.h" | 
|  | #include "gpu/command_buffer/service/sampler_manager.h" | 
|  | #include "gpu/gpu_export.h" | 
|  | #include "ui/gfx/geometry/rect.h" | 
|  | #include "ui/gl/gl_image.h" | 
|  |  | 
|  | namespace gpu { | 
|  | namespace gles2 { | 
|  |  | 
|  | class GLES2Decoder; | 
|  | class GLStreamTextureImage; | 
|  | struct ContextState; | 
|  | struct DecoderFramebufferState; | 
|  | class ErrorState; | 
|  | class FeatureInfo; | 
|  | class FramebufferManager; | 
|  | class MailboxManager; | 
|  | class ProgressReporter; | 
|  | class Texture; | 
|  | class TextureManager; | 
|  | class TextureRef; | 
|  |  | 
|  | class GPU_EXPORT TextureBase { | 
|  | public: | 
|  | explicit TextureBase(GLuint service_id); | 
|  | virtual ~TextureBase(); | 
|  |  | 
|  | // The service side OpenGL id of the texture. | 
|  | GLuint service_id() const { return service_id_; } | 
|  |  | 
|  | // Returns the target this texure was first bound to or 0 if it has not | 
|  | // been bound. Once a texture is bound to a specific target it can never be | 
|  | // bound to a different target. | 
|  | GLenum target() const { return target_; } | 
|  |  | 
|  | protected: | 
|  | // The id of the texture. | 
|  | GLuint service_id_; | 
|  |  | 
|  | // The target. 0 if unset, otherwise GL_TEXTURE_2D or GL_TEXTURE_CUBE_MAP. | 
|  | //             Or GL_TEXTURE_2D_ARRAY or GL_TEXTURE_3D (for GLES3). | 
|  | GLenum target_; | 
|  |  | 
|  | void SetTarget(GLenum target); | 
|  |  | 
|  | void DeleteFromMailboxManager(); | 
|  |  | 
|  | private: | 
|  | friend class MailboxManagerSync; | 
|  | friend class MailboxManagerImpl; | 
|  |  | 
|  | void SetMailboxManager(MailboxManager* mailbox_manager); | 
|  |  | 
|  | MailboxManager* mailbox_manager_; | 
|  | }; | 
|  |  | 
|  | // A ref-counted version of the TextureBase class that deletes the texture after | 
|  | // all references have been released. | 
|  | class TexturePassthrough final : public TextureBase, | 
|  | public base::RefCounted<TexturePassthrough> { | 
|  | public: | 
|  | TexturePassthrough(GLuint service_id, GLenum target); | 
|  |  | 
|  | // Notify the texture that the context is lost and it shouldn't delete the | 
|  | // native GL texture in the destructor | 
|  | void MarkContextLost(); | 
|  |  | 
|  | protected: | 
|  | ~TexturePassthrough() override; | 
|  |  | 
|  | private: | 
|  | friend class base::RefCounted<TexturePassthrough>; | 
|  |  | 
|  | bool have_context_; | 
|  |  | 
|  | DISALLOW_COPY_AND_ASSIGN(TexturePassthrough); | 
|  | }; | 
|  |  | 
|  | // Info about Textures currently in the system. | 
|  | // 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 final : public TextureBase { | 
|  | public: | 
|  | enum ImageState { | 
|  | // If an image is associated with the texture and image state is UNBOUND, | 
|  | // then sampling out of the texture or using it as a target for drawing | 
|  | // will not read/write from/to the image. | 
|  | UNBOUND, | 
|  | // If image state is BOUND, then sampling from the texture will return the | 
|  | // contents of the image and using it as a target will modify the image. | 
|  | BOUND, | 
|  | // Image state is set to COPIED if the contents of the image has been | 
|  | // copied to the texture. Sampling from the texture will be equivalent | 
|  | // to sampling out the image (assuming image has not been changed since | 
|  | // it was copied). Using the texture as a target for drawing will only | 
|  | // modify the texture and not the image. | 
|  | COPIED | 
|  | }; | 
|  |  | 
|  | struct CompatibilitySwizzle { | 
|  | GLenum format; | 
|  | GLenum dest_format; | 
|  | GLenum red; | 
|  | GLenum green; | 
|  | GLenum blue; | 
|  | GLenum alpha; | 
|  | }; | 
|  |  | 
|  | explicit Texture(GLuint service_id); | 
|  |  | 
|  | const SamplerState& sampler_state() const { | 
|  | return sampler_state_; | 
|  | } | 
|  |  | 
|  | GLenum min_filter() const { | 
|  | return sampler_state_.min_filter; | 
|  | } | 
|  |  | 
|  | GLenum mag_filter() const { | 
|  | return sampler_state_.mag_filter; | 
|  | } | 
|  |  | 
|  | GLenum wrap_r() const { | 
|  | return sampler_state_.wrap_r; | 
|  | } | 
|  |  | 
|  | GLenum wrap_s() const { | 
|  | return sampler_state_.wrap_s; | 
|  | } | 
|  |  | 
|  | GLenum wrap_t() const { | 
|  | return sampler_state_.wrap_t; | 
|  | } | 
|  |  | 
|  | GLenum usage() const { | 
|  | return usage_; | 
|  | } | 
|  |  | 
|  | GLenum compare_func() const { | 
|  | return sampler_state_.compare_func; | 
|  | } | 
|  |  | 
|  | GLenum compare_mode() const { | 
|  | return sampler_state_.compare_mode; | 
|  | } | 
|  |  | 
|  | GLfloat max_lod() const { | 
|  | return sampler_state_.max_lod; | 
|  | } | 
|  |  | 
|  | GLfloat min_lod() const { | 
|  | return sampler_state_.min_lod; | 
|  | } | 
|  |  | 
|  | GLint base_level() const { | 
|  | return base_level_; | 
|  | } | 
|  |  | 
|  | GLint max_level() const { | 
|  | return max_level_; | 
|  | } | 
|  |  | 
|  | GLenum swizzle_r() const { return swizzle_r_; } | 
|  |  | 
|  | GLenum swizzle_g() const { return swizzle_g_; } | 
|  |  | 
|  | GLenum swizzle_b() const { return swizzle_b_; } | 
|  |  | 
|  | GLenum swizzle_a() const { return swizzle_a_; } | 
|  |  | 
|  | int num_uncleared_mips() const { | 
|  | return num_uncleared_mips_; | 
|  | } | 
|  |  | 
|  | uint32_t estimated_size() const { return estimated_size_; } | 
|  |  | 
|  | bool CanRenderTo(const FeatureInfo* feature_info, GLint level) const; | 
|  |  | 
|  | void SetServiceId(GLuint service_id) { | 
|  | DCHECK(service_id); | 
|  | DCHECK_EQ(owned_service_id_, service_id_); | 
|  | service_id_ = service_id; | 
|  | owned_service_id_ = service_id; | 
|  | } | 
|  |  | 
|  | bool SafeToRenderFrom() const { | 
|  | return cleared_; | 
|  | } | 
|  |  | 
|  | // Get the width/height/depth for a particular level. Returns false if level | 
|  | // does not exist. | 
|  | // |depth| is optional and can be nullptr. | 
|  | bool GetLevelSize( | 
|  | GLint target, GLint level, | 
|  | GLsizei* width, GLsizei* height, GLsizei* depth) const; | 
|  |  | 
|  | // Get the type of a level. Returns false if level does not exist. | 
|  | bool GetLevelType( | 
|  | GLint target, GLint level, GLenum* type, GLenum* internal_format) const; | 
|  |  | 
|  | // Set the image for a particular level. If a GLStreamTextureImage was | 
|  | // previously set with SetLevelStreamTextureImage(), this will reset | 
|  | // |service_id_| back to |owned_service_id_|, removing the service id override | 
|  | // set by the GLStreamTextureImage. | 
|  | void SetLevelImage(GLenum target, | 
|  | GLint level, | 
|  | gl::GLImage* image, | 
|  | ImageState state); | 
|  |  | 
|  | // Set the GLStreamTextureImage for a particular level.  This is like | 
|  | // SetLevelImage, but it also makes it optional to override |service_id_| with | 
|  | // a texture bound to the stream texture, and permits | 
|  | // GetLevelStreamTextureImage to return the image. See | 
|  | // SetStreamTextureServiceId() for the details of how |service_id| is used. | 
|  | void SetLevelStreamTextureImage(GLenum target, | 
|  | GLint level, | 
|  | GLStreamTextureImage* image, | 
|  | ImageState state, | 
|  | GLuint service_id); | 
|  |  | 
|  | // Set the ImageState for the image bound to the given level. | 
|  | void SetLevelImageState(GLenum target, GLint level, ImageState state); | 
|  |  | 
|  |  | 
|  | // Get the image associated with a particular level. Returns NULL if level | 
|  | // does not exist. | 
|  | gl::GLImage* GetLevelImage(GLint target, | 
|  | GLint level, | 
|  | ImageState* state) const; | 
|  | gl::GLImage* GetLevelImage(GLint target, GLint level) const; | 
|  |  | 
|  | // Like GetLevelImage, but will return NULL if the image wasn't set via | 
|  | // a call to SetLevelStreamTextureImage. | 
|  | GLStreamTextureImage* GetLevelStreamTextureImage(GLint target, | 
|  | GLint level) const; | 
|  |  | 
|  | bool HasImages() const { | 
|  | return has_images_; | 
|  | } | 
|  |  | 
|  | // Returns true of the given dimensions are inside the dimensions of the | 
|  | // level. | 
|  | bool ValidForTexture( | 
|  | GLint target, | 
|  | GLint level, | 
|  | GLint xoffset, | 
|  | GLint yoffset, | 
|  | GLint zoffset, | 
|  | GLsizei width, | 
|  | GLsizei height, | 
|  | GLsizei depth) const; | 
|  |  | 
|  | bool IsValid() const { | 
|  | return !!target(); | 
|  | } | 
|  |  | 
|  | bool IsAttachedToFramebuffer() const { | 
|  | return framebuffer_attachment_count_ != 0; | 
|  | } | 
|  |  | 
|  | void AttachToFramebuffer() { | 
|  | ++framebuffer_attachment_count_; | 
|  | } | 
|  |  | 
|  | void DetachFromFramebuffer() { | 
|  | DCHECK_GT(framebuffer_attachment_count_, 0); | 
|  | --framebuffer_attachment_count_; | 
|  | } | 
|  |  | 
|  | void SetImmutable(bool immutable) { | 
|  | immutable_ = immutable; | 
|  | } | 
|  |  | 
|  | bool IsImmutable() const { | 
|  | return immutable_; | 
|  | } | 
|  |  | 
|  | // Return 0 if it's not immutable. | 
|  | GLint GetImmutableLevels() const; | 
|  |  | 
|  | // Get the cleared rectangle for a particular level. Returns an empty | 
|  | // rectangle if level does not exist. | 
|  | gfx::Rect GetLevelClearedRect(GLenum target, GLint level) const; | 
|  |  | 
|  | // Whether a particular level/face is cleared. | 
|  | bool IsLevelCleared(GLenum target, GLint level) const; | 
|  | // Whether a particular level/face is partially cleared. | 
|  | bool IsLevelPartiallyCleared(GLenum target, GLint level) const; | 
|  |  | 
|  | // Whether the texture has been defined | 
|  | bool IsDefined() const { | 
|  | return estimated_size() > 0; | 
|  | } | 
|  |  | 
|  | // Initialize TEXTURE_MAX_ANISOTROPY to 1 if we haven't done so yet. | 
|  | void InitTextureMaxAnisotropyIfNeeded(GLenum target); | 
|  |  | 
|  | void DumpLevelMemory(base::trace_event::ProcessMemoryDump* pmd, | 
|  | uint64_t client_tracing_id, | 
|  | const std::string& dump_name) const; | 
|  |  | 
|  | void ApplyFormatWorkarounds(FeatureInfo* feature_info); | 
|  |  | 
|  | bool EmulatingRGB(); | 
|  |  | 
|  | static bool ColorRenderable(const FeatureInfo* feature_info, | 
|  | GLenum internal_format, | 
|  | bool immutable); | 
|  |  | 
|  | private: | 
|  | friend class MailboxManagerImpl; | 
|  | friend class MailboxManagerSync; | 
|  | friend class MailboxManagerTest; | 
|  | friend class TextureDefinition; | 
|  | friend class TextureManager; | 
|  | friend class TextureRef; | 
|  | friend class TextureTestHelper; | 
|  |  | 
|  | ~Texture() override; | 
|  | 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_NEEDS_VALIDATION, | 
|  | }; | 
|  |  | 
|  | struct LevelInfo { | 
|  | LevelInfo(); | 
|  | LevelInfo(const LevelInfo& rhs); | 
|  | ~LevelInfo(); | 
|  |  | 
|  | gfx::Rect cleared_rect; | 
|  | GLenum target; | 
|  | GLint level; | 
|  | GLenum internal_format; | 
|  | GLsizei width; | 
|  | GLsizei height; | 
|  | GLsizei depth; | 
|  | GLint border; | 
|  | GLenum format; | 
|  | GLenum type; | 
|  | scoped_refptr<gl::GLImage> image; | 
|  | scoped_refptr<GLStreamTextureImage> stream_texture_image; | 
|  | ImageState image_state; | 
|  | uint32_t estimated_size; | 
|  | bool internal_workaround; | 
|  | }; | 
|  |  | 
|  | struct FaceInfo { | 
|  | FaceInfo(); | 
|  | FaceInfo(const FaceInfo& other); | 
|  | ~FaceInfo(); | 
|  |  | 
|  | // This is relative to base_level and max_level of a texture. | 
|  | GLsizei num_mip_levels; | 
|  | // This contains slots for all levels starting at 0. | 
|  | std::vector<LevelInfo> level_infos; | 
|  | }; | 
|  |  | 
|  | // Helper for SetLevel*Image.  |stream_texture_image| may be null. | 
|  | void SetLevelImageInternal(GLenum target, | 
|  | GLint level, | 
|  | gl::GLImage* image, | 
|  | GLStreamTextureImage* stream_texture_image, | 
|  | ImageState state); | 
|  |  | 
|  | // Returns the LevelInfo for |target| and |level| if it's set, else NULL. | 
|  | const LevelInfo* GetLevelInfo(GLint target, GLint level) const; | 
|  |  | 
|  | // Set the info for a particular level. | 
|  | void SetLevelInfo(GLenum target, | 
|  | GLint level, | 
|  | GLenum internal_format, | 
|  | GLsizei width, | 
|  | GLsizei height, | 
|  | GLsizei depth, | 
|  | GLint border, | 
|  | GLenum format, | 
|  | GLenum type, | 
|  | const gfx::Rect& cleared_rect); | 
|  |  | 
|  | // Causes us to report |service_id| as our service id, but does not delete | 
|  | // it when we are destroyed.  Will rebind any OES_EXTERNAL texture units to | 
|  | // our new service id in all contexts.  If |service_id| is zero, then we | 
|  | // revert to |owned_service_id_|. | 
|  | void SetStreamTextureServiceId(GLuint service_id); | 
|  |  | 
|  | void MarkLevelAsInternalWorkaround(GLenum target, GLint level); | 
|  |  | 
|  | // In GLES2 "texture complete" means it has all required mips for filtering | 
|  | // down to a 1x1 pixel texture, they are in the correct order, they are all | 
|  | // the same format. | 
|  | bool texture_complete() const { | 
|  | return texture_complete_; | 
|  | } | 
|  |  | 
|  | // In GLES2 "cube complete" means all 6 faces level 0 are defined, all the | 
|  | // same format, all the same dimensions and all width = height. | 
|  | bool cube_complete() const { | 
|  | return cube_complete_; | 
|  | } | 
|  |  | 
|  | // Whether or not this texture is a non-power-of-two texture. | 
|  | bool npot() const { | 
|  | return npot_; | 
|  | } | 
|  |  | 
|  | // Marks a |rect| of a particular level as cleared. | 
|  | void SetLevelClearedRect(GLenum target, | 
|  | GLint level, | 
|  | const gfx::Rect& cleared_rect); | 
|  |  | 
|  | // Marks a particular level as cleared or uncleared. | 
|  | void SetLevelCleared(GLenum target, GLint level, bool cleared); | 
|  |  | 
|  | // Updates the cleared flag for this texture by inspecting all the mips. | 
|  | void UpdateCleared(); | 
|  |  | 
|  | // Clears any renderable uncleared levels. | 
|  | // Returns false if a GL error was generated. | 
|  | bool ClearRenderableLevels(GLES2Decoder* decoder); | 
|  |  | 
|  | // Clears the level. | 
|  | // Returns false if a GL error was generated. | 
|  | bool ClearLevel(GLES2Decoder* decoder, GLenum target, GLint level); | 
|  |  | 
|  | // Sets a texture parameter. | 
|  | // TODO(gman): Expand to SetParameteriv,fv | 
|  | // Returns GL_NO_ERROR on success. Otherwise the error to generate. | 
|  | GLenum SetParameteri( | 
|  | const FeatureInfo* feature_info, GLenum pname, GLint param); | 
|  | GLenum SetParameterf( | 
|  | const FeatureInfo* feature_info, GLenum pname, GLfloat param); | 
|  |  | 
|  | // Makes each of the mip levels as though they were generated. | 
|  | void MarkMipmapsGenerated(); | 
|  |  | 
|  | bool NeedsMips() const { | 
|  | return sampler_state_.min_filter != GL_NEAREST && | 
|  | sampler_state_.min_filter != GL_LINEAR; | 
|  | } | 
|  |  | 
|  | // True if this texture meets all the GLES2 criteria for rendering. | 
|  | // See section 3.8.2 of the GLES2 spec. | 
|  | bool CanRender(const FeatureInfo* feature_info) const; | 
|  | bool CanRenderWithSampler(const FeatureInfo* feature_info, | 
|  | const SamplerState& sampler_state) const; | 
|  |  | 
|  | // Returns true if mipmaps can be generated by GL. | 
|  | bool CanGenerateMipmaps(const FeatureInfo* feature_info) const; | 
|  |  | 
|  | // Returns true if any of the texture dimensions are not a power of two. | 
|  | static bool TextureIsNPOT(GLsizei width, GLsizei height, GLsizei depth); | 
|  |  | 
|  | // Returns true if texture face is complete relative to the first face. | 
|  | static bool TextureFaceComplete(const Texture::LevelInfo& first_face, | 
|  | size_t face_index, | 
|  | GLenum target, | 
|  | GLenum internal_format, | 
|  | GLsizei width, | 
|  | GLsizei height, | 
|  | GLsizei depth, | 
|  | GLenum format, | 
|  | GLenum type); | 
|  |  | 
|  | // Returns true if texture mip level is complete relative to base level. | 
|  | // Note that level_diff = level - base_level. | 
|  | static bool TextureMipComplete(const Texture::LevelInfo& base_level_face, | 
|  | GLenum target, | 
|  | GLint level_diff, | 
|  | GLenum internal_format, | 
|  | GLsizei width, | 
|  | GLsizei height, | 
|  | GLsizei depth, | 
|  | GLenum format, | 
|  | GLenum type); | 
|  |  | 
|  | static bool TextureFilterable(const FeatureInfo* feature_info, | 
|  | GLenum internal_format, | 
|  | GLenum type, | 
|  | bool immutable); | 
|  |  | 
|  | // Sets the Texture's target | 
|  | // Parameters: | 
|  | //   target: GL_TEXTURE_2D or GL_TEXTURE_CUBE_MAP or | 
|  | //           GL_TEXTURE_EXTERNAL_OES or GL_TEXTURE_RECTANGLE_ARB | 
|  | //           GL_TEXTURE_2D_ARRAY or GL_TEXTURE_3D (for GLES3) | 
|  | //   max_levels: The maximum levels this type of target can have. | 
|  | void SetTarget(GLenum target, GLint max_levels); | 
|  |  | 
|  | // Update info about this texture. | 
|  | void Update(); | 
|  |  | 
|  | // Appends a signature for the given level. | 
|  | void AddToSignature( | 
|  | 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, | 
|  | GLsizei width, | 
|  | GLsizei height, | 
|  | const gfx::Rect& cleared_rect); | 
|  |  | 
|  | // Computes the CanRenderCondition flag. | 
|  | CanRenderCondition GetCanRenderCondition() const; | 
|  |  | 
|  | // Updates the unrenderable texture count in all the managers referencing this | 
|  | // texture. | 
|  | void UpdateCanRenderCondition(); | 
|  |  | 
|  | // Updates the images count in all the managers referencing this | 
|  | // texture. | 
|  | void UpdateHasImages(); | 
|  |  | 
|  | // Updates the flag that indicates whether this texture requires RGB | 
|  | // emulation. | 
|  | void UpdateEmulatingRGB(); | 
|  |  | 
|  | // Increment the framebuffer state change count in all the managers | 
|  | // referencing this texture. | 
|  | void IncAllFramebufferStateChangeCount(); | 
|  |  | 
|  | void UpdateBaseLevel(GLint base_level); | 
|  | void UpdateMaxLevel(GLint max_level); | 
|  | void UpdateNumMipLevels(); | 
|  |  | 
|  | // Increment the generation counter for all managers that have a reference to | 
|  | // this texture. | 
|  | void IncrementManagerServiceIdGeneration(); | 
|  |  | 
|  | // Return the service id of the texture that we will delete when we are | 
|  | // destroyed. | 
|  | GLuint owned_service_id() const { return owned_service_id_; } | 
|  |  | 
|  | GLenum GetCompatibilitySwizzleForChannel(GLenum channel); | 
|  | void SetCompatibilitySwizzle(const CompatibilitySwizzle* swizzle); | 
|  |  | 
|  | // Info about each face and level of texture. | 
|  | std::vector<FaceInfo> face_infos_; | 
|  |  | 
|  | // 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 texture that we are responsible for deleting.  Normally, this | 
|  | // is the same as |service_id_|, unless a GLStreamTextureImage with its own | 
|  | // service id is bound. In that case the GLStreamTextureImage service id is | 
|  | // stored in |service_id_| and overrides the owned service id for all purposes | 
|  | // except deleting the texture name. | 
|  | GLuint owned_service_id_; | 
|  |  | 
|  | // Whether all renderable mips of this texture have been cleared. | 
|  | bool cleared_; | 
|  |  | 
|  | int num_uncleared_mips_; | 
|  | int num_npot_faces_; | 
|  |  | 
|  | // Texture parameters. | 
|  | SamplerState sampler_state_; | 
|  | GLenum usage_; | 
|  | GLint base_level_; | 
|  | GLint max_level_; | 
|  | GLenum swizzle_r_; | 
|  | GLenum swizzle_g_; | 
|  | GLenum swizzle_b_; | 
|  | GLenum swizzle_a_; | 
|  |  | 
|  | // The maximum level that has been set. | 
|  | GLint max_level_set_; | 
|  |  | 
|  | // Whether or not this texture is "texture complete" | 
|  | bool texture_complete_; | 
|  |  | 
|  | // Whether mip levels have changed and should be reverified. | 
|  | bool texture_mips_dirty_; | 
|  |  | 
|  | // Whether or not this texture is "cube complete" | 
|  | bool cube_complete_; | 
|  |  | 
|  | // Whether or not this texture is non-power-of-two | 
|  | bool npot_; | 
|  |  | 
|  | // Whether this texture has ever been bound. | 
|  | bool has_been_bound_; | 
|  |  | 
|  | // The number of framebuffers this texture is attached to. | 
|  | int framebuffer_attachment_count_; | 
|  |  | 
|  | // Whether the texture is immutable and no further changes to the format | 
|  | // or dimensions of the texture object can be made. | 
|  | bool immutable_; | 
|  |  | 
|  | // Whether or not this texture has images. | 
|  | bool has_images_; | 
|  |  | 
|  | // Size in bytes this texture is assumed to take in memory. | 
|  | uint32_t estimated_size_; | 
|  |  | 
|  | // Cache of the computed CanRenderCondition flag. | 
|  | CanRenderCondition can_render_condition_; | 
|  |  | 
|  | // Whether we have initialized TEXTURE_MAX_ANISOTROPY to 1. | 
|  | bool texture_max_anisotropy_initialized_; | 
|  |  | 
|  | const CompatibilitySwizzle* compatibility_swizzle_; | 
|  |  | 
|  | bool emulating_rgb_; | 
|  |  | 
|  | 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, GLuint client_id, Texture* texture); | 
|  | static scoped_refptr<TextureRef> Create(TextureManager* manager, | 
|  | GLuint client_id, | 
|  | GLuint service_id); | 
|  |  | 
|  | void AddObserver() { num_observers_++; } | 
|  | void RemoveObserver() { num_observers_--; } | 
|  |  | 
|  | const Texture* texture() const { return texture_; } | 
|  | Texture* texture() { return texture_; } | 
|  | GLuint client_id() const { return client_id_; } | 
|  | GLuint service_id() const { return texture_->service_id(); } | 
|  | GLint num_observers() const { return num_observers_; } | 
|  |  | 
|  | // When the TextureRef is destroyed, it will assume that the context has been | 
|  | // lost, regardless of the state of the TextureManager. | 
|  | void ForceContextLost(); | 
|  |  | 
|  | private: | 
|  | friend class base::RefCounted<TextureRef>; | 
|  | friend class Texture; | 
|  | friend class TextureManager; | 
|  |  | 
|  | ~TextureRef(); | 
|  | const TextureManager* manager() const { return manager_; } | 
|  | TextureManager* manager() { return manager_; } | 
|  | void reset_client_id() { client_id_ = 0; } | 
|  |  | 
|  | TextureManager* manager_; | 
|  | Texture* texture_; | 
|  | GLuint client_id_; | 
|  | GLint num_observers_; | 
|  | bool force_context_lost_; | 
|  |  | 
|  | DISALLOW_COPY_AND_ASSIGN(TextureRef); | 
|  | }; | 
|  |  | 
|  | // Holds data that is per gles2_cmd_decoder, but is related to to the | 
|  | // TextureManager. | 
|  | struct DecoderTextureState { | 
|  | // total_texture_upload_time automatically initialized to 0 in default | 
|  | // constructor. | 
|  | explicit DecoderTextureState(const GpuDriverBugWorkarounds& workarounds) | 
|  | : tex_image_failed(false), | 
|  | texture_upload_count(0), | 
|  | texsubimage_faster_than_teximage( | 
|  | workarounds.texsubimage_faster_than_teximage), | 
|  | force_cube_map_positive_x_allocation( | 
|  | workarounds.force_cube_map_positive_x_allocation), | 
|  | force_cube_complete(workarounds.force_cube_complete), | 
|  | unpack_alignment_workaround_with_unpack_buffer( | 
|  | workarounds.unpack_alignment_workaround_with_unpack_buffer), | 
|  | unpack_overlapping_rows_separately_unpack_buffer( | 
|  | workarounds.unpack_overlapping_rows_separately_unpack_buffer), | 
|  | unpack_image_height_workaround_with_unpack_buffer( | 
|  | workarounds.unpack_image_height_workaround_with_unpack_buffer) {} | 
|  |  | 
|  | // This indicates all the following texSubImage*D calls that are part of the | 
|  | // failed texImage*D call should be ignored. The client calls have a lock | 
|  | // around them, so it will affect only a single texImage*D + texSubImage*D | 
|  | // group. | 
|  | bool tex_image_failed; | 
|  |  | 
|  | // Command buffer stats. | 
|  | int texture_upload_count; | 
|  | base::TimeDelta total_texture_upload_time; | 
|  |  | 
|  | bool texsubimage_faster_than_teximage; | 
|  | bool force_cube_map_positive_x_allocation; | 
|  | bool force_cube_complete; | 
|  | bool unpack_alignment_workaround_with_unpack_buffer; | 
|  | bool unpack_overlapping_rows_separately_unpack_buffer; | 
|  | bool unpack_image_height_workaround_with_unpack_buffer; | 
|  | }; | 
|  |  | 
|  | // This class keeps track of the textures and their sizes so we can do NPOT and | 
|  | // texture complete checking. | 
|  | // | 
|  | // NOTE: To support shared resources an instance of this class will need to be | 
|  | // shared by multiple GLES2Decoders. | 
|  | class GPU_EXPORT TextureManager : public base::trace_event::MemoryDumpProvider { | 
|  | public: | 
|  | class GPU_EXPORT DestructionObserver { | 
|  | public: | 
|  | DestructionObserver(); | 
|  | virtual ~DestructionObserver(); | 
|  |  | 
|  | // Called in ~TextureManager. | 
|  | virtual void OnTextureManagerDestroying(TextureManager* manager) = 0; | 
|  |  | 
|  | // Called via ~TextureRef. | 
|  | virtual void OnTextureRefDestroying(TextureRef* texture) = 0; | 
|  |  | 
|  | private: | 
|  | DISALLOW_COPY_AND_ASSIGN(DestructionObserver); | 
|  | }; | 
|  |  | 
|  | enum DefaultAndBlackTextures { | 
|  | kTexture2D, | 
|  | kTexture3D, | 
|  | kTexture2DArray, | 
|  | kCubeMap, | 
|  | kExternalOES, | 
|  | kRectangleARB, | 
|  | kNumDefaultTextures | 
|  | }; | 
|  |  | 
|  | TextureManager(MemoryTracker* memory_tracker, | 
|  | FeatureInfo* feature_info, | 
|  | GLsizei max_texture_size, | 
|  | GLsizei max_cube_map_texture_size, | 
|  | GLsizei max_rectangle_texture_size, | 
|  | GLsizei max_3d_texture_size, | 
|  | GLsizei max_array_texture_layers, | 
|  | bool use_default_textures, | 
|  | ProgressReporter* progress_reporter); | 
|  | ~TextureManager() override; | 
|  |  | 
|  | void set_framebuffer_manager(FramebufferManager* manager) { | 
|  | framebuffer_manager_ = manager; | 
|  | } | 
|  |  | 
|  | // Init the texture manager. | 
|  | bool Initialize(); | 
|  |  | 
|  | // Must call before destruction. | 
|  | void Destroy(bool have_context); | 
|  |  | 
|  | // Returns the maximum number of levels. | 
|  | GLint MaxLevelsForTarget(GLenum target) const { | 
|  | switch (target) { | 
|  | case GL_TEXTURE_2D: | 
|  | case GL_TEXTURE_2D_ARRAY: | 
|  | return max_levels_; | 
|  | case GL_TEXTURE_RECTANGLE_ARB: | 
|  | case GL_TEXTURE_EXTERNAL_OES: | 
|  | return 1; | 
|  | case GL_TEXTURE_3D: | 
|  | return max_3d_levels_; | 
|  | default: | 
|  | return max_cube_map_levels_; | 
|  | } | 
|  | } | 
|  |  | 
|  | // Returns the maximum size. | 
|  | GLsizei MaxSizeForTarget(GLenum target) const { | 
|  | switch (target) { | 
|  | case GL_TEXTURE_2D: | 
|  | case GL_TEXTURE_EXTERNAL_OES: | 
|  | case GL_TEXTURE_2D_ARRAY: | 
|  | return max_texture_size_; | 
|  | case GL_TEXTURE_RECTANGLE: | 
|  | return max_rectangle_texture_size_; | 
|  | case GL_TEXTURE_3D: | 
|  | return max_3d_texture_size_; | 
|  | default: | 
|  | return max_cube_map_texture_size_; | 
|  | } | 
|  | } | 
|  |  | 
|  | GLsizei max_array_texture_layers() const { | 
|  | return max_array_texture_layers_; | 
|  | } | 
|  |  | 
|  | // Returns the maxium number of levels a texture of the given size can have. | 
|  | static GLsizei ComputeMipMapCount(GLenum target, | 
|  | GLsizei width, | 
|  | GLsizei height, | 
|  | GLsizei depth); | 
|  |  | 
|  | static GLenum ExtractFormatFromStorageFormat(GLenum internalformat); | 
|  | static GLenum ExtractTypeFromStorageFormat(GLenum internalformat); | 
|  |  | 
|  | // Checks if a dimensions are valid for a given target. | 
|  | bool ValidForTarget( | 
|  | GLenum target, GLint level, | 
|  | GLsizei width, GLsizei height, GLsizei depth); | 
|  |  | 
|  | // True if this texture meets all the GLES2 criteria for rendering. | 
|  | // See section 3.8.2 of the GLES2 spec. | 
|  | bool CanRender(const TextureRef* ref) const { | 
|  | return ref->texture()->CanRender(feature_info_.get()); | 
|  | } | 
|  |  | 
|  | bool CanRenderWithSampler( | 
|  | const TextureRef* ref, const SamplerState& sampler_state) const { | 
|  | return ref->texture()->CanRenderWithSampler( | 
|  | feature_info_.get(), sampler_state); | 
|  | } | 
|  |  | 
|  | // Returns true if mipmaps can be generated by GL. | 
|  | bool CanGenerateMipmaps(const TextureRef* ref) const { | 
|  | return ref->texture()->CanGenerateMipmaps(feature_info_.get()); | 
|  | } | 
|  |  | 
|  | // Sets the Texture's target | 
|  | // Parameters: | 
|  | //   target: GL_TEXTURE_2D or GL_TEXTURE_CUBE_MAP | 
|  | //           GL_TEXTURE_2D_ARRAY or GL_TEXTURE_3D (for GLES3) | 
|  | //   max_levels: The maximum levels this type of target can have. | 
|  | void SetTarget( | 
|  | TextureRef* ref, | 
|  | GLenum target); | 
|  |  | 
|  | // Set the info for a particular level in a TexureInfo. | 
|  | void SetLevelInfo(TextureRef* ref, | 
|  | GLenum target, | 
|  | GLint level, | 
|  | GLenum internal_format, | 
|  | GLsizei width, | 
|  | GLsizei height, | 
|  | GLsizei depth, | 
|  | GLint border, | 
|  | GLenum format, | 
|  | GLenum type, | 
|  | const gfx::Rect& cleared_rect); | 
|  |  | 
|  | Texture* Produce(TextureRef* ref); | 
|  |  | 
|  | // Maps an existing texture into the texture manager, at a given client ID. | 
|  | TextureRef* Consume(GLuint client_id, Texture* texture); | 
|  |  | 
|  | // Sets |rect| of mip as cleared. | 
|  | void SetLevelClearedRect(TextureRef* ref, | 
|  | GLenum target, | 
|  | GLint level, | 
|  | const gfx::Rect& cleared_rect); | 
|  |  | 
|  | // Sets a mip as cleared. | 
|  | void SetLevelCleared(TextureRef* ref, GLenum target, | 
|  | GLint level, bool cleared); | 
|  |  | 
|  | // Sets a texture parameter of a Texture | 
|  | // Returns GL_NO_ERROR on success. Otherwise the error to generate. | 
|  | // TODO(gman): Expand to SetParameteriv,fv | 
|  | void SetParameteri( | 
|  | const char* function_name, ErrorState* error_state, | 
|  | TextureRef* ref, GLenum pname, GLint param); | 
|  | void SetParameterf( | 
|  | const char* function_name, ErrorState* error_state, | 
|  | TextureRef* ref, GLenum pname, GLfloat param); | 
|  |  | 
|  | // Makes each of the mip levels as though they were generated. | 
|  | void MarkMipmapsGenerated(TextureRef* ref); | 
|  |  | 
|  | // Clears any uncleared renderable levels. | 
|  | bool ClearRenderableLevels(GLES2Decoder* decoder, TextureRef* ref); | 
|  |  | 
|  | // Clear a specific level. | 
|  | bool ClearTextureLevel( | 
|  | GLES2Decoder* decoder, TextureRef* ref, GLenum target, GLint level); | 
|  |  | 
|  | // Creates a new texture info. | 
|  | TextureRef* CreateTexture(GLuint client_id, GLuint service_id); | 
|  |  | 
|  | // Gets the texture info for the given texture. | 
|  | TextureRef* GetTexture(GLuint client_id) const; | 
|  |  | 
|  | // Removes a texture info. | 
|  | void RemoveTexture(GLuint client_id); | 
|  |  | 
|  | // Gets a Texture for a given service id (note: it assumes the texture object | 
|  | // is still mapped in this TextureManager). | 
|  | Texture* GetTextureForServiceId(GLuint service_id) const; | 
|  |  | 
|  | TextureRef* GetDefaultTextureInfo(GLenum target) { | 
|  | switch (target) { | 
|  | case GL_TEXTURE_2D: | 
|  | return default_textures_[kTexture2D].get(); | 
|  | case GL_TEXTURE_3D: | 
|  | return default_textures_[kTexture3D].get(); | 
|  | case GL_TEXTURE_2D_ARRAY: | 
|  | return default_textures_[kTexture2DArray].get(); | 
|  | case GL_TEXTURE_CUBE_MAP: | 
|  | return default_textures_[kCubeMap].get(); | 
|  | case GL_TEXTURE_EXTERNAL_OES: | 
|  | return default_textures_[kExternalOES].get(); | 
|  | case GL_TEXTURE_RECTANGLE_ARB: | 
|  | return default_textures_[kRectangleARB].get(); | 
|  | default: | 
|  | NOTREACHED(); | 
|  | return NULL; | 
|  | } | 
|  | } | 
|  |  | 
|  | bool HaveUnsafeTextures() const { | 
|  | return num_unsafe_textures_ > 0; | 
|  | } | 
|  |  | 
|  | bool HaveUnclearedMips() const { | 
|  | return num_uncleared_mips_ > 0; | 
|  | } | 
|  |  | 
|  | bool HaveImages() const { | 
|  | return num_images_ > 0; | 
|  | } | 
|  |  | 
|  | GLuint black_texture_id(GLenum target) const { | 
|  | switch (target) { | 
|  | case GL_SAMPLER_2D: | 
|  | return black_texture_ids_[kTexture2D]; | 
|  | case GL_SAMPLER_3D: | 
|  | return black_texture_ids_[kTexture3D]; | 
|  | case GL_SAMPLER_2D_ARRAY: | 
|  | return black_texture_ids_[kTexture2DArray]; | 
|  | case GL_SAMPLER_CUBE: | 
|  | return black_texture_ids_[kCubeMap]; | 
|  | case GL_SAMPLER_EXTERNAL_OES: | 
|  | return black_texture_ids_[kExternalOES]; | 
|  | case GL_SAMPLER_2D_RECT_ARB: | 
|  | return black_texture_ids_[kRectangleARB]; | 
|  | default: | 
|  | NOTREACHED(); | 
|  | return 0; | 
|  | } | 
|  | } | 
|  |  | 
|  | size_t mem_represented() const { | 
|  | return memory_type_tracker_->GetMemRepresented(); | 
|  | } | 
|  |  | 
|  | void SetLevelImage(TextureRef* ref, | 
|  | GLenum target, | 
|  | GLint level, | 
|  | gl::GLImage* image, | 
|  | Texture::ImageState state); | 
|  |  | 
|  | void SetLevelStreamTextureImage(TextureRef* ref, | 
|  | GLenum target, | 
|  | GLint level, | 
|  | GLStreamTextureImage* image, | 
|  | Texture::ImageState state, | 
|  | GLuint service_id); | 
|  |  | 
|  | void SetLevelImageState(TextureRef* ref, | 
|  | GLenum target, | 
|  | GLint level, | 
|  | Texture::ImageState state); | 
|  |  | 
|  | size_t GetSignatureSize() const; | 
|  |  | 
|  | void AddToSignature( | 
|  | TextureRef* ref, | 
|  | GLenum target, | 
|  | GLint level, | 
|  | std::string* signature) const; | 
|  |  | 
|  | void AddObserver(DestructionObserver* observer) { | 
|  | destruction_observers_.push_back(observer); | 
|  | } | 
|  |  | 
|  | void RemoveObserver(DestructionObserver* observer) { | 
|  | for (unsigned int i = 0; i < destruction_observers_.size(); i++) { | 
|  | if (destruction_observers_[i] == observer) { | 
|  | std::swap(destruction_observers_[i], destruction_observers_.back()); | 
|  | destruction_observers_.pop_back(); | 
|  | return; | 
|  | } | 
|  | } | 
|  | NOTREACHED(); | 
|  | } | 
|  |  | 
|  | struct DoTexImageArguments { | 
|  | enum TexImageCommandType { | 
|  | kTexImage2D, | 
|  | kTexImage3D, | 
|  | }; | 
|  |  | 
|  | GLenum target; | 
|  | GLint level; | 
|  | GLenum internal_format; | 
|  | GLsizei width; | 
|  | GLsizei height; | 
|  | GLsizei depth; | 
|  | GLint border; | 
|  | GLenum format; | 
|  | GLenum type; | 
|  | const void* pixels; | 
|  | uint32_t pixels_size; | 
|  | uint32_t padding; | 
|  | TexImageCommandType command_type; | 
|  | }; | 
|  |  | 
|  | bool ValidateTexImage( | 
|  | ContextState* state, | 
|  | const char* function_name, | 
|  | const DoTexImageArguments& args, | 
|  | // Pointer to TextureRef filled in if validation successful. | 
|  | // Presumes the pointer is valid. | 
|  | TextureRef** texture_ref); | 
|  |  | 
|  | void ValidateAndDoTexImage( | 
|  | DecoderTextureState* texture_state, | 
|  | ContextState* state, | 
|  | DecoderFramebufferState* framebuffer_state, | 
|  | const char* function_name, | 
|  | const DoTexImageArguments& args); | 
|  |  | 
|  | struct DoTexSubImageArguments { | 
|  | enum TexSubImageCommandType { | 
|  | kTexSubImage2D, | 
|  | kTexSubImage3D, | 
|  | }; | 
|  |  | 
|  | GLenum target; | 
|  | GLint level; | 
|  | GLint xoffset; | 
|  | GLint yoffset; | 
|  | GLint zoffset; | 
|  | GLsizei width; | 
|  | GLsizei height; | 
|  | GLsizei depth; | 
|  | GLenum format; | 
|  | GLenum type; | 
|  | const void* pixels; | 
|  | uint32_t pixels_size; | 
|  | uint32_t padding; | 
|  | TexSubImageCommandType command_type; | 
|  | }; | 
|  |  | 
|  | bool ValidateTexSubImage( | 
|  | ContextState* state, | 
|  | const char* function_name, | 
|  | const DoTexSubImageArguments& args, | 
|  | // Pointer to TextureRef filled in if validation successful. | 
|  | // Presumes the pointer is valid. | 
|  | TextureRef** texture_ref); | 
|  |  | 
|  | void ValidateAndDoTexSubImage(GLES2Decoder* decoder, | 
|  | DecoderTextureState* texture_state, | 
|  | ContextState* state, | 
|  | DecoderFramebufferState* framebuffer_state, | 
|  | const char* function_name, | 
|  | const DoTexSubImageArguments& args); | 
|  |  | 
|  | // TODO(kloveless): Make GetTexture* private once this is no longer called | 
|  | // from gles2_cmd_decoder. | 
|  | TextureRef* GetTextureInfoForTarget(ContextState* state, GLenum target); | 
|  | TextureRef* GetTextureInfoForTargetUnlessDefault( | 
|  | ContextState* state, GLenum target); | 
|  |  | 
|  | // This function is used to validate TexImage2D and TexSubImage2D and their | 
|  | // variants. But internal_format only checked for callers of TexImage2D and | 
|  | // its variants (tex_image_call is true). | 
|  | bool ValidateTextureParameters( | 
|  | ErrorState* error_state, const char* function_name, bool tex_image_call, | 
|  | GLenum format, GLenum type, GLint internal_format, GLint level); | 
|  |  | 
|  | // base::trace_event::MemoryDumpProvider implementation. | 
|  | bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args, | 
|  | base::trace_event::ProcessMemoryDump* pmd) override; | 
|  |  | 
|  | // Returns the union of |rect1| and |rect2| if one of the rectangles is empty, | 
|  | // contains the other rectangle or shares an edge with the other rectangle. | 
|  | // Part of the public interface because texture pixel data rectangle | 
|  | // operations are also implemented in decoder at the moment. | 
|  | static bool CombineAdjacentRects(const gfx::Rect& rect1, | 
|  | const gfx::Rect& rect2, | 
|  | gfx::Rect* result); | 
|  |  | 
|  | // Get / set the current generation number of this manager.  This generation | 
|  | // number changes whenever the service_id of one or more Textures change. | 
|  | uint32_t GetServiceIdGeneration() const; | 
|  | void IncrementServiceIdGeneration(); | 
|  |  | 
|  | static GLenum AdjustTexInternalFormat(const gles2::FeatureInfo* feature_info, | 
|  | GLenum format); | 
|  | static GLenum AdjustTexFormat(const gles2::FeatureInfo* feature_info, | 
|  | GLenum format); | 
|  |  | 
|  | void WorkaroundCopyTexImageCubeMap( | 
|  | DecoderTextureState* texture_state, | 
|  | ContextState* state, | 
|  | DecoderFramebufferState* framebuffer_state, | 
|  | TextureRef* texture_ref, | 
|  | const char* function_name, | 
|  | const DoTexImageArguments& args) { | 
|  | DoCubeMapWorkaround(texture_state, state, framebuffer_state, | 
|  | texture_ref, function_name, args); | 
|  | } | 
|  |  | 
|  | private: | 
|  | friend class Texture; | 
|  | friend class TextureRef; | 
|  |  | 
|  | // Helper for Initialize(). | 
|  | scoped_refptr<TextureRef> CreateDefaultAndBlackTextures( | 
|  | GLenum target, | 
|  | GLuint* black_texture); | 
|  |  | 
|  | void DoTexImage( | 
|  | DecoderTextureState* texture_state, | 
|  | ContextState* state, | 
|  | DecoderFramebufferState* framebuffer_state, | 
|  | const char* function_name, | 
|  | TextureRef* texture_ref, | 
|  | const DoTexImageArguments& args); | 
|  |  | 
|  | // Reserve memory for the texture and set its attributes so it can be filled | 
|  | // with TexSubImage. The image contents are undefined after this function, | 
|  | // so make sure it's subsequently filled in its entirety. | 
|  | void ReserveTexImageToBeFilled(DecoderTextureState* texture_state, | 
|  | ContextState* state, | 
|  | DecoderFramebufferState* framebuffer_state, | 
|  | const char* function_name, | 
|  | TextureRef* texture_ref, | 
|  | const DoTexImageArguments& args); | 
|  |  | 
|  | void DoTexSubImageWithAlignmentWorkaround( | 
|  | DecoderTextureState* texture_state, | 
|  | ContextState* state, | 
|  | const DoTexSubImageArguments& args); | 
|  |  | 
|  | void DoTexSubImageRowByRowWorkaround(DecoderTextureState* texture_state, | 
|  | ContextState* state, | 
|  | const DoTexSubImageArguments& args, | 
|  | const PixelStoreParams& unpack_params); | 
|  |  | 
|  | void DoTexSubImageLayerByLayerWorkaround( | 
|  | DecoderTextureState* texture_state, | 
|  | ContextState* state, | 
|  | const DoTexSubImageArguments& args, | 
|  | const PixelStoreParams& unpack_params); | 
|  |  | 
|  | void DoCubeMapWorkaround( | 
|  | DecoderTextureState* texture_state, | 
|  | ContextState* state, | 
|  | DecoderFramebufferState* framebuffer_state, | 
|  | TextureRef* texture_ref, | 
|  | const char* function_name, | 
|  | const DoTexImageArguments& args); | 
|  |  | 
|  | 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 UpdateNumImages(int delta); | 
|  | void IncFramebufferStateChangeCount(); | 
|  |  | 
|  | // Helper function called by OnMemoryDump. | 
|  | void DumpTextureRef(base::trace_event::ProcessMemoryDump* pmd, | 
|  | TextureRef* ref); | 
|  |  | 
|  | MemoryTypeTracker* GetMemTracker(); | 
|  | std::unique_ptr<MemoryTypeTracker> memory_type_tracker_; | 
|  | MemoryTracker* memory_tracker_; | 
|  |  | 
|  | scoped_refptr<FeatureInfo> feature_info_; | 
|  |  | 
|  | FramebufferManager* framebuffer_manager_; | 
|  |  | 
|  | // Info for each texture in the system. | 
|  | typedef base::hash_map<GLuint, scoped_refptr<TextureRef> > TextureMap; | 
|  | TextureMap textures_; | 
|  |  | 
|  | GLsizei max_texture_size_; | 
|  | GLsizei max_cube_map_texture_size_; | 
|  | GLsizei max_rectangle_texture_size_; | 
|  | GLsizei max_3d_texture_size_; | 
|  | GLsizei max_array_texture_layers_; | 
|  | GLint max_levels_; | 
|  | GLint max_cube_map_levels_; | 
|  | GLint max_3d_levels_; | 
|  |  | 
|  | const bool use_default_textures_; | 
|  |  | 
|  | int num_unsafe_textures_; | 
|  | int num_uncleared_mips_; | 
|  | int num_images_; | 
|  |  | 
|  | // Counts the number of Textures allocated with 'this' as its manager. | 
|  | // Allows to check no Texture will outlive this. | 
|  | unsigned int texture_count_; | 
|  |  | 
|  | bool have_context_; | 
|  |  | 
|  | // Black (0,0,0,1) textures for when non-renderable textures are used. | 
|  | // NOTE: There is no corresponding Texture for these textures. | 
|  | // TextureInfos are only for textures the client side can access. | 
|  | GLuint black_texture_ids_[kNumDefaultTextures]; | 
|  |  | 
|  | // The default textures for each target (texture name = 0) | 
|  | scoped_refptr<TextureRef> default_textures_[kNumDefaultTextures]; | 
|  |  | 
|  | std::vector<DestructionObserver*> destruction_observers_; | 
|  |  | 
|  | uint32_t current_service_id_generation_; | 
|  |  | 
|  | // Used to notify the watchdog thread of progress during destruction, | 
|  | // preventing time-outs when destruction takes a long time. May be null when | 
|  | // using in-process command buffer. | 
|  | ProgressReporter* progress_reporter_; | 
|  |  | 
|  | DISALLOW_COPY_AND_ASSIGN(TextureManager); | 
|  | }; | 
|  |  | 
|  | // This class records texture upload time when in scope. | 
|  | class ScopedTextureUploadTimer { | 
|  | public: | 
|  | explicit ScopedTextureUploadTimer(DecoderTextureState* texture_state); | 
|  | ~ScopedTextureUploadTimer(); | 
|  |  | 
|  | private: | 
|  | DecoderTextureState* texture_state_; | 
|  | base::TimeTicks begin_time_; | 
|  | DISALLOW_COPY_AND_ASSIGN(ScopedTextureUploadTimer); | 
|  | }; | 
|  |  | 
|  | }  // namespace gles2 | 
|  | }  // namespace gpu | 
|  |  | 
|  | #endif  // GPU_COMMAND_BUFFER_SERVICE_TEXTURE_MANAGER_H_ |