1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef GPU_COMMAND_BUFFER_SERVICE_TEXTURE_MANAGER_H_
6 #define GPU_COMMAND_BUFFER_SERVICE_TEXTURE_MANAGER_H_
12 #include "base/basictypes.h"
13 #include "base/containers/hash_tables.h"
14 #include "base/logging.h"
15 #include "base/memory/ref_counted.h"
16 #include "base/observer_list.h"
17 #include "gpu/command_buffer/service/async_pixel_transfer_delegate.h"
18 #include "gpu/command_buffer/service/gl_utils.h"
19 #include "gpu/command_buffer/service/memory_tracking.h"
20 #include "gpu/gpu_export.h"
21 #include "ui/gl/gl_image.h"
25 class StreamTextureManager;
31 struct DecoderFramebufferState;
35 class FramebufferManager;
40 // Info about Textures currently in the system.
41 // This class wraps a real GL texture, keeping track of its meta-data. It is
42 // jointly owned by possibly multiple TextureRef.
43 class GPU_EXPORT Texture {
45 explicit Texture(GLuint service_id);
47 GLenum min_filter() const {
51 GLenum mag_filter() const {
55 GLenum wrap_s() const {
59 GLenum wrap_t() const {
63 GLenum usage() const {
71 int num_uncleared_mips() const {
72 return num_uncleared_mips_;
75 uint32 estimated_size() const {
76 return estimated_size_;
79 bool CanRenderTo() const {
80 return !stream_texture_ && target_ != GL_TEXTURE_EXTERNAL_OES;
83 // The service side OpenGL id of the texture.
84 GLuint service_id() const {
88 void SetServiceId(GLuint service_id) {
90 service_id_ = service_id;
93 // Returns the target this texure was first bound to or 0 if it has not
94 // been bound. Once a texture is bound to a specific target it can never be
95 // bound to a different target.
96 GLenum target() const {
100 bool SafeToRenderFrom() const {
104 // Get the width and height for a particular level. Returns false if level
107 GLint target, GLint level, GLsizei* width, GLsizei* height) const;
109 // Get the type of a level. Returns false if level does not exist.
111 GLint target, GLint level, GLenum* type, GLenum* internal_format) const;
113 // Get the image bound to a particular level. Returns NULL if level
115 gfx::GLImage* GetLevelImage(GLint target, GLint level) const;
117 bool HasImages() const {
121 // Returns true of the given dimensions are inside the dimensions of the
122 // level and if the format and type match the level.
123 bool ValidForTexture(
133 bool IsValid() const {
137 bool IsAttachedToFramebuffer() const {
138 return framebuffer_attachment_count_ != 0;
141 void AttachToFramebuffer() {
142 ++framebuffer_attachment_count_;
145 void DetachFromFramebuffer() {
146 DCHECK_GT(framebuffer_attachment_count_, 0);
147 --framebuffer_attachment_count_;
150 bool IsStreamTexture() const {
151 return stream_texture_;
154 void SetImmutable(bool immutable) {
155 immutable_ = immutable;
158 bool IsImmutable() const {
162 // Whether a particular level/face is cleared.
163 bool IsLevelCleared(GLenum target, GLint level) const;
165 // Whether the texture has been defined
166 bool IsDefined() const {
167 return estimated_size() > 0;
171 friend class MailboxManager;
172 friend class MailboxManagerTest;
173 friend class TextureManager;
174 friend class TextureRef;
175 friend class TextureTestHelper;
178 void AddTextureRef(TextureRef* ref);
179 void RemoveTextureRef(TextureRef* ref, bool have_context);
180 MemoryTypeTracker* GetMemTracker();
182 // Condition on which this texture is renderable. Can be ONLY_IF_NPOT if it
183 // depends on context support for non-power-of-two textures (i.e. will be
184 // renderable if NPOT support is in the context, otherwise not, e.g. texture
185 // with a NPOT level). ALWAYS means it doesn't depend on context features
186 // (e.g. complete POT), NEVER means it's not renderable regardless (e.g.
188 enum CanRenderCondition {
191 CAN_RENDER_ONLY_IF_NPOT
196 LevelInfo(const LevelInfo& rhs);
202 GLenum internal_format;
209 scoped_refptr<gfx::GLImage> image;
210 uint32 estimated_size;
213 // Set the info for a particular level.
215 const FeatureInfo* feature_info,
218 GLenum internal_format,
227 // In GLES2 "texture complete" means it has all required mips for filtering
228 // down to a 1x1 pixel texture, they are in the correct order, they are all
230 bool texture_complete() const {
231 return texture_complete_;
234 // In GLES2 "cube complete" means all 6 faces level 0 are defined, all the
235 // same format, all the same dimensions and all width = height.
236 bool cube_complete() const {
237 return cube_complete_;
240 // Whether or not this texture is a non-power-of-two texture.
245 void SetStreamTexture(bool stream_texture) {
246 stream_texture_ = stream_texture;
247 UpdateCanRenderCondition();
250 // Marks a particular level as cleared or uncleared.
251 void SetLevelCleared(GLenum target, GLint level, bool cleared);
253 // Updates the cleared flag for this texture by inspecting all the mips.
254 void UpdateCleared();
256 // Clears any renderable uncleared levels.
257 // Returns false if a GL error was generated.
258 bool ClearRenderableLevels(GLES2Decoder* decoder);
261 // Returns false if a GL error was generated.
262 bool ClearLevel(GLES2Decoder* decoder, GLenum target, GLint level);
264 // Sets a texture parameter.
265 // TODO(gman): Expand to SetParameteri,f,iv,fv
266 // Returns GL_NO_ERROR on success. Otherwise the error to generate.
268 const FeatureInfo* feature_info, GLenum pname, GLint param);
270 // Makes each of the mip levels as though they were generated.
271 bool MarkMipmapsGenerated(const FeatureInfo* feature_info);
273 bool NeedsMips() const {
274 return min_filter_ != GL_NEAREST && min_filter_ != GL_LINEAR;
277 // True if this texture meets all the GLES2 criteria for rendering.
278 // See section 3.8.2 of the GLES2 spec.
279 bool CanRender(const FeatureInfo* feature_info) const;
281 // Returns true if mipmaps can be generated by GL.
282 bool CanGenerateMipmaps(const FeatureInfo* feature_info) const;
284 // Sets the Texture's target
286 // target: GL_TEXTURE_2D or GL_TEXTURE_CUBE_MAP or
287 // GL_TEXTURE_EXTERNAL_OES or GL_TEXTURE_RECTANGLE_ARB
288 // max_levels: The maximum levels this type of target can have.
290 const FeatureInfo* feature_info, GLenum target, GLint max_levels);
292 // Update info about this texture.
293 void Update(const FeatureInfo* feature_info);
295 // Set the image for a particular level.
297 const FeatureInfo* feature_info,
300 gfx::GLImage* image);
302 // Appends a signature for the given level.
304 const FeatureInfo* feature_info,
305 GLenum target, GLint level, std::string* signature) const;
307 void SetMailboxManager(MailboxManager* mailbox_manager);
309 // Updates the unsafe textures count in all the managers referencing this
311 void UpdateSafeToRenderFrom(bool cleared);
313 // Updates the uncleared mip count in all the managers referencing this
315 void UpdateMipCleared(LevelInfo* info, bool cleared);
317 // Computes the CanRenderCondition flag.
318 CanRenderCondition GetCanRenderCondition() const;
320 // Updates the unrenderable texture count in all the managers referencing this
322 void UpdateCanRenderCondition();
324 // Updates the images count in all the managers referencing this
326 void UpdateHasImages();
328 // Increment the framebuffer state change count in all the managers
329 // referencing this texture.
330 void IncAllFramebufferStateChangeCount();
332 MailboxManager* mailbox_manager_;
334 // Info about each face and level of texture.
335 std::vector<std::vector<LevelInfo> > level_infos_;
337 // The texture refs that point to this Texture.
338 typedef std::set<TextureRef*> RefSet;
341 // The single TextureRef that accounts for memory for this texture. Must be
343 TextureRef* memory_tracking_ref_;
345 // The id of the texure
348 // Whether all renderable mips of this texture have been cleared.
351 int num_uncleared_mips_;
353 // The target. 0 if unset, otherwise GL_TEXTURE_2D or GL_TEXTURE_CUBE_MAP.
356 // Texture parameters.
364 // The maximum level that has been set.
365 GLint max_level_set_;
367 // Whether or not this texture is "texture complete"
368 bool texture_complete_;
370 // Whether or not this texture is "cube complete"
373 // Whether or not this texture is non-power-of-two
376 // Whether this texture has ever been bound.
377 bool has_been_bound_;
379 // The number of framebuffers this texture is attached to.
380 int framebuffer_attachment_count_;
382 // Whether this is a special streaming texture.
383 bool stream_texture_;
385 // Whether the texture is immutable and no further changes to the format
386 // or dimensions of the texture object can be made.
389 // Whether or not this texture has images.
392 // Size in bytes this texture is assumed to take in memory.
393 uint32 estimated_size_;
395 // Cache of the computed CanRenderCondition flag.
396 CanRenderCondition can_render_condition_;
398 DISALLOW_COPY_AND_ASSIGN(Texture);
401 // This class represents a texture in a client context group. It's mostly 1:1
402 // with a client id, though it can outlive the client id if it's still bound to
403 // a FBO or another context when destroyed.
404 // Multiple TextureRef can point to the same texture with cross-context sharing.
406 // Note: for stream textures, the TextureRef that created the stream texture is
407 // set as the "owner" of the stream texture, i.e. it will call
408 // DestroyStreamTexture on destruction. This is because the StreamTextureManager
409 // isn't generally shared between ContextGroups, so ownership can't be at the
410 // Texture level. We also can't have multiple StreamTexture on the same service
411 // id, so there can be only one owner.
412 class GPU_EXPORT TextureRef : public base::RefCounted<TextureRef> {
414 TextureRef(TextureManager* manager, GLuint client_id, Texture* texture);
415 static scoped_refptr<TextureRef> Create(TextureManager* manager,
418 const Texture* texture() const { return texture_; }
419 Texture* texture() { return texture_; }
420 GLuint client_id() const { return client_id_; }
421 GLuint service_id() const { return texture_->service_id(); }
424 friend class base::RefCounted<TextureRef>;
425 friend class Texture;
426 friend class TextureManager;
429 const TextureManager* manager() const { return manager_; }
430 TextureManager* manager() { return manager_; }
431 void reset_client_id() { client_id_ = 0; }
432 void set_is_stream_texture_owner(bool owner) {
433 is_stream_texture_owner_ = owner;
435 bool is_stream_texture_owner() const { return is_stream_texture_owner_; }
437 TextureManager* manager_;
440 bool is_stream_texture_owner_;
442 DISALLOW_COPY_AND_ASSIGN(TextureRef);
445 // Holds data that is per gles2_cmd_decoder, but is related to to the
447 struct DecoderTextureState {
448 // total_texture_upload_time automatically initialized to 0 in default
450 DecoderTextureState():
451 tex_image_2d_failed(false),
452 texture_upload_count(0),
453 teximage2d_faster_than_texsubimage2d(true) {}
455 // This indicates all the following texSubImage2D calls that are part of the
456 // failed texImage2D call should be ignored.
457 bool tex_image_2d_failed;
459 // Command buffer stats.
460 int texture_upload_count;
461 base::TimeDelta total_texture_upload_time;
463 // This is really not per-decoder, but the logic to decide this value is in
464 // the decoder for now, so it is simpler to leave it there.
465 bool teximage2d_faster_than_texsubimage2d;
468 // This class keeps track of the textures and their sizes so we can do NPOT and
469 // texture complete checking.
471 // NOTE: To support shared resources an instance of this class will need to be
472 // shared by multiple GLES2Decoders.
473 class GPU_EXPORT TextureManager {
475 class GPU_EXPORT DestructionObserver {
477 DestructionObserver();
478 virtual ~DestructionObserver();
480 // Called in ~TextureManager.
481 virtual void OnTextureManagerDestroying(TextureManager* manager) = 0;
483 // Called via ~TextureRef.
484 virtual void OnTextureRefDestroying(TextureRef* texture) = 0;
487 DISALLOW_COPY_AND_ASSIGN(DestructionObserver);
490 enum DefaultAndBlackTextures {
498 TextureManager(MemoryTracker* memory_tracker,
499 FeatureInfo* feature_info,
500 GLsizei max_texture_size,
501 GLsizei max_cube_map_texture_size);
504 void set_framebuffer_manager(FramebufferManager* manager) {
505 framebuffer_manager_ = manager;
508 void set_stream_texture_manager(StreamTextureManager* manager) {
509 stream_texture_manager_ = manager;
512 // Init the texture manager.
515 // Must call before destruction.
516 void Destroy(bool have_context);
518 // Returns the maximum number of levels.
519 GLint MaxLevelsForTarget(GLenum target) const {
523 case GL_TEXTURE_EXTERNAL_OES:
526 return max_cube_map_levels_;
530 // Returns the maximum size.
531 GLsizei MaxSizeForTarget(GLenum target) const {
534 case GL_TEXTURE_EXTERNAL_OES:
535 return max_texture_size_;
537 return max_cube_map_texture_size_;
541 // Returns the maxium number of levels a texture of the given size can have.
542 static GLsizei ComputeMipMapCount(GLenum target,
547 // Checks if a dimensions are valid for a given target.
549 GLenum target, GLint level,
550 GLsizei width, GLsizei height, GLsizei depth);
552 // True if this texture meets all the GLES2 criteria for rendering.
553 // See section 3.8.2 of the GLES2 spec.
554 bool CanRender(const TextureRef* ref) const {
555 return ref->texture()->CanRender(feature_info_.get());
558 // Returns true if mipmaps can be generated by GL.
559 bool CanGenerateMipmaps(const TextureRef* ref) const {
560 return ref->texture()->CanGenerateMipmaps(feature_info_.get());
563 // Sets the Texture's target
565 // target: GL_TEXTURE_2D or GL_TEXTURE_CUBE_MAP
566 // max_levels: The maximum levels this type of target can have.
571 // Marks a texture as a stream texture, and the ref as the stream texture
573 void SetStreamTexture(TextureRef* ref, bool stream_texture);
575 // Whether the TextureRef is the stream texture owner.
576 bool IsStreamTextureOwner(TextureRef* ref);
578 // Set the info for a particular level in a TexureInfo.
583 GLenum internal_format,
592 // Adapter to call above function.
593 void SetLevelInfoFromParams(TextureRef* ref,
594 const gpu::AsyncTexImage2DParams& params) {
596 ref, params.target, params.level, params.internal_format,
597 params.width, params.height, 1 /* depth */,
598 params.border, params.format,
599 params.type, true /* cleared */ );
602 Texture* Produce(TextureRef* ref);
604 // Maps an existing texture into the texture manager, at a given client ID.
605 TextureRef* Consume(GLuint client_id, Texture* texture);
607 // Sets a mip as cleared.
608 void SetLevelCleared(TextureRef* ref, GLenum target,
609 GLint level, bool cleared);
611 // Sets a texture parameter of a Texture
612 // Returns GL_NO_ERROR on success. Otherwise the error to generate.
613 // TODO(gman): Expand to SetParameteri,f,iv,fv
615 const char* function_name, ErrorState* error_state,
616 TextureRef* ref, GLenum pname, GLint param);
618 // Makes each of the mip levels as though they were generated.
619 // Returns false if that's not allowed for the given texture.
620 bool MarkMipmapsGenerated(TextureRef* ref);
622 // Clears any uncleared renderable levels.
623 bool ClearRenderableLevels(GLES2Decoder* decoder, TextureRef* ref);
625 // Clear a specific level.
626 bool ClearTextureLevel(
627 GLES2Decoder* decoder, TextureRef* ref, GLenum target, GLint level);
629 // Creates a new texture info.
630 TextureRef* CreateTexture(GLuint client_id, GLuint service_id);
632 // Gets the texture info for the given texture.
633 TextureRef* GetTexture(GLuint client_id) const;
635 // Removes a texture info.
636 void RemoveTexture(GLuint client_id);
638 // Gets a Texture for a given service id (note: it assumes the texture object
639 // is still mapped in this TextureManager).
640 Texture* GetTextureForServiceId(GLuint service_id) const;
642 TextureRef* GetDefaultTextureInfo(GLenum target) {
645 return default_textures_[kTexture2D].get();
646 case GL_TEXTURE_CUBE_MAP:
647 return default_textures_[kCubeMap].get();
648 case GL_TEXTURE_EXTERNAL_OES:
649 return default_textures_[kExternalOES].get();
650 case GL_TEXTURE_RECTANGLE_ARB:
651 return default_textures_[kRectangleARB].get();
658 bool HaveUnrenderableTextures() const {
659 return num_unrenderable_textures_ > 0;
662 bool HaveUnsafeTextures() const {
663 return num_unsafe_textures_ > 0;
666 bool HaveUnclearedMips() const {
667 return num_uncleared_mips_ > 0;
670 bool HaveImages() const {
671 return num_images_ > 0;
674 GLuint black_texture_id(GLenum target) const {
677 return black_texture_ids_[kTexture2D];
678 case GL_SAMPLER_CUBE:
679 return black_texture_ids_[kCubeMap];
680 case GL_SAMPLER_EXTERNAL_OES:
681 return black_texture_ids_[kExternalOES];
682 case GL_SAMPLER_2D_RECT_ARB:
683 return black_texture_ids_[kRectangleARB];
690 size_t mem_represented() const {
692 memory_tracker_managed_->GetMemRepresented() +
693 memory_tracker_unmanaged_->GetMemRepresented();
700 gfx::GLImage* image);
706 std::string* signature) const;
708 void AddObserver(DestructionObserver* observer) {
709 destruction_observers_.AddObserver(observer);
712 void RemoveObserver(DestructionObserver* observer) {
713 destruction_observers_.RemoveObserver(observer);
716 struct DoTextImage2DArguments {
719 GLenum internal_format;
729 bool ValidateTexImage2D(
731 const char* function_name,
732 const DoTextImage2DArguments& args,
733 // Pointer to TextureRef filled in if validation successful.
734 // Presumes the pointer is valid.
735 TextureRef** texture_ref);
737 void ValidateAndDoTexImage2D(
738 DecoderTextureState* texture_state,
740 DecoderFramebufferState* framebuffer_state,
741 const DoTextImage2DArguments& args);
743 // TODO(kloveless): Make GetTexture* private once this is no longer called
744 // from gles2_cmd_decoder.
745 TextureRef* GetTextureInfoForTarget(ContextState* state, GLenum target);
746 TextureRef* GetTextureInfoForTargetUnlessDefault(
747 ContextState* state, GLenum target);
749 bool ValidateTextureParameters(
750 ErrorState* error_state, const char* function_name,
751 GLenum target, GLenum format, GLenum type, GLint level);
754 friend class Texture;
755 friend class TextureRef;
757 // Helper for Initialize().
758 scoped_refptr<TextureRef> CreateDefaultAndBlackTextures(
760 GLuint* black_texture);
763 DecoderTextureState* texture_state,
764 ErrorState* error_state,
765 DecoderFramebufferState* framebuffer_state,
766 TextureRef* texture_ref,
767 const DoTextImage2DArguments& args);
769 void StartTracking(TextureRef* texture);
770 void StopTracking(TextureRef* texture);
772 void UpdateSafeToRenderFrom(int delta);
773 void UpdateUnclearedMips(int delta);
774 void UpdateCanRenderCondition(Texture::CanRenderCondition old_condition,
775 Texture::CanRenderCondition new_condition);
776 void UpdateNumImages(int delta);
777 void IncFramebufferStateChangeCount();
779 MemoryTypeTracker* GetMemTracker(GLenum texture_pool);
780 scoped_ptr<MemoryTypeTracker> memory_tracker_managed_;
781 scoped_ptr<MemoryTypeTracker> memory_tracker_unmanaged_;
783 scoped_refptr<FeatureInfo> feature_info_;
785 FramebufferManager* framebuffer_manager_;
786 StreamTextureManager* stream_texture_manager_;
788 // Info for each texture in the system.
789 typedef base::hash_map<GLuint, scoped_refptr<TextureRef> > TextureMap;
790 TextureMap textures_;
792 GLsizei max_texture_size_;
793 GLsizei max_cube_map_texture_size_;
795 GLint max_cube_map_levels_;
797 int num_unrenderable_textures_;
798 int num_unsafe_textures_;
799 int num_uncleared_mips_;
802 // Counts the number of Textures allocated with 'this' as its manager.
803 // Allows to check no Texture will outlive this.
804 unsigned int texture_count_;
808 // Black (0,0,0,1) textures for when non-renderable textures are used.
809 // NOTE: There is no corresponding Texture for these textures.
810 // TextureInfos are only for textures the client side can access.
811 GLuint black_texture_ids_[kNumDefaultTextures];
813 // The default textures for each target (texture name = 0)
814 scoped_refptr<TextureRef> default_textures_[kNumDefaultTextures];
816 ObserverList<DestructionObserver> destruction_observers_;
818 DISALLOW_COPY_AND_ASSIGN(TextureManager);
821 // This class records texture upload time when in scope.
822 class ScopedTextureUploadTimer {
824 explicit ScopedTextureUploadTimer(DecoderTextureState* texture_state);
825 ~ScopedTextureUploadTimer();
828 DecoderTextureState* texture_state_;
829 base::TimeTicks begin_time_;
830 DISALLOW_COPY_AND_ASSIGN(ScopedTextureUploadTimer);
836 #endif // GPU_COMMAND_BUFFER_SERVICE_TEXTURE_MANAGER_H_