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_RENDERBUFFER_MANAGER_H_
6#define GPU_COMMAND_BUFFER_SERVICE_RENDERBUFFER_MANAGER_H_
7
8#include <string>
9#include "base/basictypes.h"
10#include "base/containers/hash_tables.h"
11#include "base/memory/ref_counted.h"
12#include "base/memory/scoped_ptr.h"
13#include "gpu/command_buffer/service/gl_utils.h"
14#include "gpu/command_buffer/service/memory_tracking.h"
15#include "gpu/gpu_export.h"
16
17namespace gpu {
18namespace gles2 {
19
20class RenderbufferManager;
21
22// Info about a Renderbuffer.
23class GPU_EXPORT Renderbuffer
24    : public base::RefCounted<Renderbuffer> {
25 public:
26  Renderbuffer(RenderbufferManager* manager,
27               GLuint client_id,
28               GLuint service_id);
29
30  GLuint service_id() const {
31    return service_id_;
32  }
33
34  GLuint client_id() const {
35    return client_id_;
36  }
37
38  bool cleared() const {
39    return cleared_;
40  }
41
42  GLenum internal_format() const {
43    return internal_format_;
44  }
45
46  GLsizei samples() const {
47    return samples_;
48  }
49
50  GLsizei width() const {
51    return width_;
52  }
53
54  GLsizei height() const {
55    return height_;
56  }
57
58  bool IsDeleted() const {
59    return client_id_ == 0;
60  }
61
62  void MarkAsValid() {
63    has_been_bound_ = true;
64  }
65
66  bool IsValid() const {
67    return has_been_bound_ && !IsDeleted();
68  }
69
70  size_t EstimatedSize();
71
72  void AddToSignature(std::string* signature) const;
73
74 private:
75  friend class RenderbufferManager;
76  friend class base::RefCounted<Renderbuffer>;
77
78  ~Renderbuffer();
79
80  void set_cleared(bool cleared) {
81    cleared_ = cleared;
82  }
83
84  void SetInfo(
85      GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) {
86    samples_ = samples;
87    internal_format_ = internalformat;
88    width_ = width;
89    height_ = height;
90    cleared_ = false;
91  }
92
93  void MarkAsDeleted() {
94    client_id_ = 0;
95  }
96
97  // RenderbufferManager that owns this Renderbuffer.
98  RenderbufferManager* manager_;
99
100  // Client side renderbuffer id.
101  GLuint client_id_;
102
103  // Service side renderbuffer id.
104  GLuint service_id_;
105
106  // Whether this renderbuffer has been cleared
107  bool cleared_;
108
109  // Whether this renderbuffer has ever been bound.
110  bool has_been_bound_;
111
112  // Number of samples (for multi-sampled renderbuffers)
113  GLsizei samples_;
114
115  // Renderbuffer internalformat set through RenderbufferStorage().
116  GLenum internal_format_;
117
118  // Dimensions of renderbuffer.
119  GLsizei width_;
120  GLsizei height_;
121};
122
123// This class keeps track of the renderbuffers and whether or not they have
124// been cleared.
125class GPU_EXPORT RenderbufferManager {
126 public:
127  RenderbufferManager(MemoryTracker* memory_tracker,
128                      GLint max_renderbuffer_size,
129                      GLint max_samples);
130  ~RenderbufferManager();
131
132  GLint max_renderbuffer_size() const {
133    return max_renderbuffer_size_;
134  }
135
136  GLint max_samples() const {
137    return max_samples_;
138  }
139
140  bool HaveUnclearedRenderbuffers() const {
141    return num_uncleared_renderbuffers_ != 0;
142  }
143
144  void SetInfo(
145      Renderbuffer* renderbuffer,
146      GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
147
148  void SetCleared(Renderbuffer* renderbuffer, bool cleared);
149
150  // Must call before destruction.
151  void Destroy(bool have_context);
152
153  // Creates a Renderbuffer for the given renderbuffer ids.
154  void CreateRenderbuffer(GLuint client_id, GLuint service_id);
155
156  // Gets the renderbuffer for the given renderbuffer id.
157  Renderbuffer* GetRenderbuffer(GLuint client_id);
158
159  // Removes a renderbuffer for the given renderbuffer id.
160  void RemoveRenderbuffer(GLuint client_id);
161
162  size_t mem_represented() const {
163    return memory_tracker_->GetMemRepresented();
164  }
165
166  static bool ComputeEstimatedRenderbufferSize(
167      int width, int height, int samples, int internal_format, uint32* size);
168  static GLenum InternalRenderbufferFormatToImplFormat(GLenum impl_format);
169
170 private:
171  friend class Renderbuffer;
172
173  void StartTracking(Renderbuffer* renderbuffer);
174  void StopTracking(Renderbuffer* renderbuffer);
175
176  scoped_ptr<MemoryTypeTracker> memory_tracker_;
177
178  GLint max_renderbuffer_size_;
179  GLint max_samples_;
180
181  int num_uncleared_renderbuffers_;
182
183  // Counts the number of Renderbuffer allocated with 'this' as its manager.
184  // Allows to check no Renderbuffer will outlive this.
185  unsigned renderbuffer_count_;
186
187  bool have_context_;
188
189  // Info for each renderbuffer in the system.
190  typedef base::hash_map<GLuint, scoped_refptr<Renderbuffer> > RenderbufferMap;
191  RenderbufferMap renderbuffers_;
192
193  DISALLOW_COPY_AND_ASSIGN(RenderbufferManager);
194};
195
196}  // namespace gles2
197}  // namespace gpu
198
199#endif  // GPU_COMMAND_BUFFER_SERVICE_RENDERBUFFER_MANAGER_H_
200