texture_manager.h revision c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d
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.
4
5#ifndef GPU_COMMAND_BUFFER_SERVICE_TEXTURE_MANAGER_H_
6#define GPU_COMMAND_BUFFER_SERVICE_TEXTURE_MANAGER_H_
7
8#include <list>
9#include <string>
10#include <vector>
11#include "base/basictypes.h"
12#include "base/hash_tables.h"
13#include "base/logging.h"
14#include "base/memory/ref_counted.h"
15#include "gpu/command_buffer/service/gl_utils.h"
16#include "gpu/command_buffer/service/memory_tracking.h"
17#include "gpu/gpu_export.h"
18#include "ui/gl/async_pixel_transfer_delegate.h"
19#include "ui/gl/gl_image.h"
20
21namespace gpu {
22namespace gles2 {
23
24class GLES2Decoder;
25class Display;
26class ErrorState;
27class FeatureInfo;
28class TextureDefinition;
29class TextureManager;
30
31// Info about Textures currently in the system.
32class GPU_EXPORT Texture : public base::RefCounted<Texture> {
33 public:
34  Texture(TextureManager* manager, GLuint service_id);
35
36  GLenum min_filter() const {
37    return min_filter_;
38  }
39
40  GLenum mag_filter() const {
41    return mag_filter_;
42  }
43
44  GLenum wrap_s() const {
45    return wrap_s_;
46  }
47
48  GLenum wrap_t() const {
49    return wrap_t_;
50  }
51
52  GLenum usage() const {
53    return usage_;
54  }
55
56  GLenum pool() const {
57    return pool_;
58  }
59
60  int num_uncleared_mips() const {
61    return num_uncleared_mips_;
62  }
63
64  uint32 estimated_size() const {
65    return estimated_size_;
66  }
67
68  bool CanRenderTo() const {
69    return !stream_texture_ && target_ != GL_TEXTURE_EXTERNAL_OES;
70  }
71
72  // The service side OpenGL id of the texture.
73  GLuint service_id() const {
74    return service_id_;
75  }
76
77  void SetServiceId(GLuint service_id) {
78    service_id_ = service_id;
79  }
80
81  // Returns the target this texure was first bound to or 0 if it has not
82  // been bound. Once a texture is bound to a specific target it can never be
83  // bound to a different target.
84  GLenum target() const {
85    return target_;
86  }
87
88  bool SafeToRenderFrom() const {
89    return cleared_;
90  }
91
92  // Get the width and height for a particular level. Returns false if level
93  // does not exist.
94  bool GetLevelSize(
95      GLint target, GLint level, GLsizei* width, GLsizei* height) const;
96
97  // Get the type of a level. Returns false if level does not exist.
98  bool GetLevelType(
99      GLint target, GLint level, GLenum* type, GLenum* internal_format) const;
100
101  // Get the image bound to a particular level. Returns NULL if level
102  // does not exist.
103  gfx::GLImage* GetLevelImage(GLint target, GLint level) const;
104
105  bool IsDeleted() const {
106    return deleted_;
107  }
108
109  // Returns true of the given dimensions are inside the dimensions of the
110  // level and if the format and type match the level.
111  bool ValidForTexture(
112      GLint target,
113      GLint level,
114      GLint xoffset,
115      GLint yoffset,
116      GLsizei width,
117      GLsizei height,
118      GLenum format,
119      GLenum type) const;
120
121  bool IsValid() const {
122    return target() && !IsDeleted();
123  }
124
125  void SetNotOwned() {
126    owned_ = false;
127  }
128
129  bool IsAttachedToFramebuffer() const {
130    return framebuffer_attachment_count_ != 0;
131  }
132
133  void AttachToFramebuffer() {
134    ++framebuffer_attachment_count_;
135  }
136
137  void DetachFromFramebuffer() {
138    DCHECK_GT(framebuffer_attachment_count_, 0);
139    --framebuffer_attachment_count_;
140  }
141
142  void SetStreamTexture(bool stream_texture) {
143    stream_texture_ = stream_texture;
144  }
145
146  bool IsStreamTexture() {
147    return stream_texture_;
148  }
149
150  gfx::AsyncPixelTransferState* GetAsyncTransferState() const {
151    return async_transfer_state_.get();
152  }
153  void SetAsyncTransferState(scoped_ptr<gfx::AsyncPixelTransferState> state) {
154    async_transfer_state_ = state.Pass();
155  }
156  bool AsyncTransferIsInProgress() {
157    return async_transfer_state_ &&
158        async_transfer_state_->TransferIsInProgress();
159  }
160
161  void SetImmutable(bool immutable) {
162    immutable_ = immutable;
163  }
164
165  bool IsImmutable() {
166    return immutable_;
167  }
168
169  // Whether a particular level/face is cleared.
170  bool IsLevelCleared(GLenum target, GLint level) const;
171
172  // Whether the texture has been defined
173  bool IsDefined() {
174    return estimated_size() > 0;
175  }
176
177 private:
178  friend class TextureManager;
179  friend class TextureTestHelper;
180  friend class base::RefCounted<Texture>;
181
182  ~Texture();
183
184  struct LevelInfo {
185    LevelInfo();
186    LevelInfo(const LevelInfo& rhs);
187    ~LevelInfo();
188
189    bool cleared;
190    GLenum target;
191    GLint level;
192    GLenum internal_format;
193    GLsizei width;
194    GLsizei height;
195    GLsizei depth;
196    GLint border;
197    GLenum format;
198    GLenum type;
199    scoped_refptr<gfx::GLImage> image;
200    uint32 estimated_size;
201  };
202
203  // Set the info for a particular level.
204  void SetLevelInfo(
205      const FeatureInfo* feature_info,
206      GLenum target,
207      GLint level,
208      GLenum internal_format,
209      GLsizei width,
210      GLsizei height,
211      GLsizei depth,
212      GLint border,
213      GLenum format,
214      GLenum type,
215      bool cleared);
216
217  // In GLES2 "texture complete" means it has all required mips for filtering
218  // down to a 1x1 pixel texture, they are in the correct order, they are all
219  // the same format.
220  bool texture_complete() const {
221    return texture_complete_;
222  }
223
224  // In GLES2 "cube complete" means all 6 faces level 0 are defined, all the
225  // same format, all the same dimensions and all width = height.
226  bool cube_complete() const {
227    return cube_complete_;
228  }
229
230  // Whether or not this texture is a non-power-of-two texture.
231  bool npot() const {
232    return npot_;
233  }
234
235  // Marks a particular level as cleared or uncleared.
236  void SetLevelCleared(GLenum target, GLint level, bool cleared);
237
238  // Updates the cleared flag for this texture by inspecting all the mips.
239  void UpdateCleared();
240
241  // Clears any renderable uncleared levels.
242  // Returns false if a GL error was generated.
243  bool ClearRenderableLevels(GLES2Decoder* decoder);
244
245  // Clears the level.
246  // Returns false if a GL error was generated.
247  bool ClearLevel(GLES2Decoder* decoder, GLenum target, GLint level);
248
249  // Sets a texture parameter.
250  // TODO(gman): Expand to SetParameteri,f,iv,fv
251  // Returns GL_NO_ERROR on success. Otherwise the error to generate.
252  GLenum SetParameter(
253      const FeatureInfo* feature_info, GLenum pname, GLint param);
254
255  // Makes each of the mip levels as though they were generated.
256  bool MarkMipmapsGenerated(const FeatureInfo* feature_info);
257
258  void MarkAsDeleted() {
259    deleted_ = true;
260  }
261
262  bool NeedsMips() const {
263    return min_filter_ != GL_NEAREST && min_filter_ != GL_LINEAR;
264  }
265
266  // True if this texture meets all the GLES2 criteria for rendering.
267  // See section 3.8.2 of the GLES2 spec.
268  bool CanRender(const FeatureInfo* feature_info) const;
269
270  // Returns true if mipmaps can be generated by GL.
271  bool CanGenerateMipmaps(const FeatureInfo* feature_info) const;
272
273  // Sets the Texture's target
274  // Parameters:
275  //   target: GL_TEXTURE_2D or GL_TEXTURE_CUBE_MAP or
276  //           GL_TEXTURE_EXTERNAL_OES or GL_TEXTURE_RECTANGLE_ARB
277  //   max_levels: The maximum levels this type of target can have.
278  void SetTarget(GLenum target, GLint max_levels);
279
280  // Update info about this texture.
281  void Update(const FeatureInfo* feature_info);
282
283  // Set the image for a particular level.
284  void SetLevelImage(
285      const FeatureInfo* feature_info,
286      GLenum target,
287      GLint level,
288      gfx::GLImage* image);
289
290  // Appends a signature for the given level.
291  void AddToSignature(
292      const FeatureInfo* feature_info,
293      GLenum target, GLint level, std::string* signature) const;
294
295  // Info about each face and level of texture.
296  std::vector<std::vector<LevelInfo> > level_infos_;
297
298  // The texture manager that manages this Texture.
299  TextureManager* manager_;
300
301  // The id of the texure
302  GLuint service_id_;
303
304  // Whether this texture has been deleted.
305  bool deleted_;
306
307  // Whether all renderable mips of this texture have been cleared.
308  bool cleared_;
309
310  int num_uncleared_mips_;
311
312  // The target. 0 if unset, otherwise GL_TEXTURE_2D or GL_TEXTURE_CUBE_MAP.
313  GLenum target_;
314
315  // Texture parameters.
316  GLenum min_filter_;
317  GLenum mag_filter_;
318  GLenum wrap_s_;
319  GLenum wrap_t_;
320  GLenum usage_;
321  GLenum pool_;
322
323  // The maximum level that has been set.
324  GLint max_level_set_;
325
326  // Whether or not this texture is "texture complete"
327  bool texture_complete_;
328
329  // Whether or not this texture is "cube complete"
330  bool cube_complete_;
331
332  // Whether or not this texture is non-power-of-two
333  bool npot_;
334
335  // Whether this texture has ever been bound.
336  bool has_been_bound_;
337
338  // The number of framebuffers this texture is attached to.
339  int framebuffer_attachment_count_;
340
341  // Whether the associated context group owns this texture and should delete
342  // it.
343  bool owned_;
344
345  // Whether this is a special streaming texture.
346  bool stream_texture_;
347
348  // State to facilitate async transfers on this texture.
349  scoped_ptr<gfx::AsyncPixelTransferState> async_transfer_state_;
350
351  // Whether the texture is immutable and no further changes to the format
352  // or dimensions of the texture object can be made.
353  bool immutable_;
354
355  // Size in bytes this texture is assumed to take in memory.
356  uint32 estimated_size_;
357
358  DISALLOW_COPY_AND_ASSIGN(Texture);
359};
360
361// This class keeps track of the textures and their sizes so we can do NPOT and
362// texture complete checking.
363//
364// NOTE: To support shared resources an instance of this class will need to be
365// shared by multiple GLES2Decoders.
366class GPU_EXPORT TextureManager {
367 public:
368  enum DefaultAndBlackTextures {
369    kTexture2D,
370    kCubeMap,
371    kExternalOES,
372    kRectangleARB,
373    kNumDefaultTextures
374  };
375
376  TextureManager(MemoryTracker* memory_tracker,
377                 FeatureInfo* feature_info,
378                 GLsizei max_texture_size,
379                 GLsizei max_cube_map_texture_size);
380  ~TextureManager();
381
382  // Init the texture manager.
383  bool Initialize();
384
385  // Must call before destruction.
386  void Destroy(bool have_context);
387
388  // Returns the maximum number of levels.
389  GLint MaxLevelsForTarget(GLenum target) const {
390    switch (target) {
391      case GL_TEXTURE_2D:
392        return  max_levels_;
393      case GL_TEXTURE_EXTERNAL_OES:
394        return 1;
395      default:
396        return max_cube_map_levels_;
397    }
398  }
399
400  // Returns the maximum size.
401  GLsizei MaxSizeForTarget(GLenum target) const {
402    switch (target) {
403      case GL_TEXTURE_2D:
404      case GL_TEXTURE_EXTERNAL_OES:
405        return max_texture_size_;
406      default:
407        return max_cube_map_texture_size_;
408    }
409  }
410
411  // Returns the maxium number of levels a texture of the given size can have.
412  static GLsizei ComputeMipMapCount(
413    GLsizei width, GLsizei height, GLsizei depth);
414
415  // Checks if a dimensions are valid for a given target.
416  bool ValidForTarget(
417      GLenum target, GLint level,
418      GLsizei width, GLsizei height, GLsizei depth);
419
420  // True if this texture meets all the GLES2 criteria for rendering.
421  // See section 3.8.2 of the GLES2 spec.
422  bool CanRender(const Texture* texture) const {
423    return texture->CanRender(feature_info_);
424  }
425
426  // Returns true if mipmaps can be generated by GL.
427  bool CanGenerateMipmaps(const Texture* texture) const {
428    return texture->CanGenerateMipmaps(feature_info_);
429  }
430
431  // Sets the Texture's target
432  // Parameters:
433  //   target: GL_TEXTURE_2D or GL_TEXTURE_CUBE_MAP
434  //   max_levels: The maximum levels this type of target can have.
435  void SetTarget(
436      Texture* texture,
437      GLenum target);
438
439  // Set the info for a particular level in a TexureInfo.
440  void SetLevelInfo(
441      Texture* texture,
442      GLenum target,
443      GLint level,
444      GLenum internal_format,
445      GLsizei width,
446      GLsizei height,
447      GLsizei depth,
448      GLint border,
449      GLenum format,
450      GLenum type,
451      bool cleared);
452
453  // Adapter to call above function.
454  void SetLevelInfoFromParams(Texture* texture,
455                              const gfx::AsyncTexImage2DParams& params) {
456    SetLevelInfo(
457        texture, params.target, params.level, params.internal_format,
458        params.width, params.height, 1 /* depth */,
459        params.border, params.format,
460        params.type, true /* cleared */ );
461  }
462
463  // Save the texture definition and leave it undefined.
464  TextureDefinition* Save(Texture* texture);
465
466  // Redefine all the levels from the texture definition.
467  bool Restore(
468      const char* function_name,
469      GLES2Decoder* decoder,
470      Texture* texture,
471      TextureDefinition* definition);
472
473  // Sets a mip as cleared.
474  void SetLevelCleared(Texture* texture, GLenum target,
475                       GLint level, bool cleared);
476
477  // Sets a texture parameter of a Texture
478  // Returns GL_NO_ERROR on success. Otherwise the error to generate.
479  // TODO(gman): Expand to SetParameteri,f,iv,fv
480  void SetParameter(
481      const char* function_name, ErrorState* error_state,
482      Texture* texture, GLenum pname, GLint param);
483
484  // Makes each of the mip levels as though they were generated.
485  // Returns false if that's not allowed for the given texture.
486  bool MarkMipmapsGenerated(Texture* texture);
487
488  // Clears any uncleared renderable levels.
489  bool ClearRenderableLevels(GLES2Decoder* decoder, Texture* texture);
490
491  // Clear a specific level.
492  bool ClearTextureLevel(
493      GLES2Decoder* decoder,Texture* texture, GLenum target, GLint level);
494
495  // Creates a new texture info.
496  Texture* CreateTexture(GLuint client_id, GLuint service_id);
497
498  // Gets the texture info for the given texture.
499  Texture* GetTexture(GLuint client_id) const;
500
501  // Removes a texture info.
502  void RemoveTexture(GLuint client_id);
503
504  // Gets a client id for a given service id.
505  bool GetClientId(GLuint service_id, GLuint* client_id) const;
506
507  Texture* GetDefaultTextureInfo(GLenum target) {
508    switch (target) {
509      case GL_TEXTURE_2D:
510        return default_textures_[kTexture2D];
511      case GL_TEXTURE_CUBE_MAP:
512        return default_textures_[kCubeMap];
513      case GL_TEXTURE_EXTERNAL_OES:
514        return default_textures_[kExternalOES];
515      case GL_TEXTURE_RECTANGLE_ARB:
516        return default_textures_[kRectangleARB];
517      default:
518        NOTREACHED();
519        return NULL;
520    }
521  }
522
523  bool HaveUnrenderableTextures() const {
524    return num_unrenderable_textures_ > 0;
525  }
526
527  bool HaveUnsafeTextures() const {
528    return num_unsafe_textures_ > 0;
529  }
530
531  bool HaveUnclearedMips() const {
532    return num_uncleared_mips_ > 0;
533  }
534
535  GLuint black_texture_id(GLenum target) const {
536    switch (target) {
537      case GL_SAMPLER_2D:
538        return black_texture_ids_[kTexture2D];
539      case GL_SAMPLER_CUBE:
540        return black_texture_ids_[kCubeMap];
541      case GL_SAMPLER_EXTERNAL_OES:
542        return black_texture_ids_[kExternalOES];
543      case GL_SAMPLER_2D_RECT_ARB:
544        return black_texture_ids_[kRectangleARB];
545      default:
546        NOTREACHED();
547        return 0;
548    }
549  }
550
551  size_t mem_represented() const {
552    return
553        memory_tracker_managed_->GetMemRepresented() +
554        memory_tracker_unmanaged_->GetMemRepresented();
555  }
556
557  void SetLevelImage(
558      Texture* texture,
559      GLenum target,
560      GLint level,
561      gfx::GLImage* image);
562
563  void AddToSignature(
564      Texture* texture,
565      GLenum target,
566      GLint level,
567      std::string* signature) const;
568
569 private:
570  friend class Texture;
571
572  // Helper for Initialize().
573  scoped_refptr<Texture> CreateDefaultAndBlackTextures(
574      GLenum target,
575      GLuint* black_texture);
576
577  void StartTracking(Texture* texture);
578  void StopTracking(Texture* texture);
579
580  MemoryTypeTracker* GetMemTracker(GLenum texture_pool);
581  scoped_ptr<MemoryTypeTracker> memory_tracker_managed_;
582  scoped_ptr<MemoryTypeTracker> memory_tracker_unmanaged_;
583
584  scoped_refptr<FeatureInfo> feature_info_;
585
586  // Info for each texture in the system.
587  typedef base::hash_map<GLuint, scoped_refptr<Texture> > TextureMap;
588  TextureMap textures_;
589
590  GLsizei max_texture_size_;
591  GLsizei max_cube_map_texture_size_;
592  GLint max_levels_;
593  GLint max_cube_map_levels_;
594
595  int num_unrenderable_textures_;
596  int num_unsafe_textures_;
597  int num_uncleared_mips_;
598
599  // Counts the number of Textures allocated with 'this' as its manager.
600  // Allows to check no Texture will outlive this.
601  unsigned int texture_count_;
602
603  bool have_context_;
604
605  // Black (0,0,0,1) textures for when non-renderable textures are used.
606  // NOTE: There is no corresponding Texture for these textures.
607  // TextureInfos are only for textures the client side can access.
608  GLuint black_texture_ids_[kNumDefaultTextures];
609
610  // The default textures for each target (texture name = 0)
611  scoped_refptr<Texture> default_textures_[kNumDefaultTextures];
612
613  DISALLOW_COPY_AND_ASSIGN(TextureManager);
614};
615
616}  // namespace gles2
617}  // namespace gpu
618
619#endif  // GPU_COMMAND_BUFFER_SERVICE_TEXTURE_MANAGER_H_
620