15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef GPU_COMMAND_BUFFER_SERVICE_BUFFER_MANAGER_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define GPU_COMMAND_BUFFER_SERVICE_BUFFER_MANAGER_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/containers/hash_tables.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/gl_utils.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "gpu/command_buffer/service/memory_tracking.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/gpu_export.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gpu {
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gles2 {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class BufferManager;
229ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdochstruct ContextState;
23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class ErrorState;
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class FeatureInfo;
259ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdochclass TestHelper;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Info about Buffers currently in the system.
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class GPU_EXPORT Buffer : public base::RefCounted<Buffer> {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Buffer(BufferManager* manager, GLuint service_id);
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GLuint service_id() const {
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return service_id_;
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GLenum target() const {
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return target_;
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GLsizeiptr size() const {
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return size_;
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GLenum usage() const {
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return usage_;
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Gets the maximum value in the buffer for the given range interpreted as
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the given type. Returns false if offset and count are out of range.
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // offset is in bytes.
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // count is in elements of type.
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool GetMaxValueForRange(GLuint offset, GLsizei count, GLenum type,
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           GLuint* max_value);
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Returns a pointer to shadowed data.
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const void* GetRange(GLintptr offset, GLsizeiptr size) const;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool IsDeleted() const {
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return deleted_;
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool IsValid() const {
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return target() && !IsDeleted();
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool IsClientSideArray() const {
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return is_client_side_array_;
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  friend class BufferManager;
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  friend class BufferManagerTestBase;
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  friend class base::RefCounted<Buffer>;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Represents a range in a buffer.
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  class Range {
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   public:
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Range(GLuint offset, GLsizei count, GLenum type)
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        : offset_(offset),
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          count_(count),
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          type_(type) {
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // A less functor provided for std::map so it can find ranges.
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    struct Less {
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      bool operator() (const Range& lhs, const Range& rhs) const {
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (lhs.offset_ != rhs.offset_) {
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          return lhs.offset_ < rhs.offset_;
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (lhs.count_ != rhs.count_) {
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          return lhs.count_ < rhs.count_;
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return lhs.type_ < rhs.type_;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    };
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   private:
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GLuint offset_;
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GLsizei count_;
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GLenum type_;
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ~Buffer();
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void set_target(GLenum target) {
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK_EQ(target_, 0u);  // you can only set this once.
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    target_ = target;
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool shadowed() const {
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return shadowed_;
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void MarkAsDeleted() {
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    deleted_ = true;
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Sets the size, usage and initial data of a buffer.
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If shadow is true then if data is NULL buffer will be initialized to 0.
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void SetInfo(
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GLsizeiptr size, GLenum usage, bool shadow, const GLvoid* data,
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      bool is_client_side_array);
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Sets a range of data for this buffer. Returns false if the offset or size
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // is out of range.
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool SetRange(
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GLintptr offset, GLsizeiptr size, const GLvoid * data);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Clears any cache of index ranges.
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void ClearCache();
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Check if an offset, size range is valid for the current buffer.
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool CheckRange(GLintptr offset, GLsizeiptr size) const;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The manager that owns this Buffer.
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BufferManager* manager_;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
138424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // A copy of the data in the buffer. This data is only kept if the target
139424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // is backed_ = true.
140424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  scoped_ptr<int8[]> shadow_;
141424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
142424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Size of buffer.
143424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  GLsizeiptr size_;
144424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // True if deleted.
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool deleted_;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
148424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Whether or not the data is shadowed.
149424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  bool shadowed_;
150424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
151424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Whether or not this Buffer is not uploaded to the GPU but just
152424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // sitting in local memory.
153424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  bool is_client_side_array_;
154424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Service side buffer id.
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GLuint service_id_;
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The type of buffer. 0 = unset, GL_BUFFER_ARRAY = vertex data,
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // GL_ELEMENT_BUFFER_ARRAY = index data.
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Once set a buffer can not be used for something else.
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GLenum target_;
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Usage of buffer.
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GLenum usage_;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // A map of ranges to the highest value in that range of a certain type.
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  typedef std::map<Range, GLuint, Range::Less> RangeToMaxValueMap;
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RangeToMaxValueMap range_set_;
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This class keeps track of the buffers and their sizes so we can do
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// bounds checking.
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// NOTE: To support shared resources an instance of this class will need to be
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// shared by multiple GLES2Decoders.
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class GPU_EXPORT BufferManager {
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BufferManager(MemoryTracker* memory_tracker, FeatureInfo* feature_info);
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~BufferManager();
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Must call before destruction.
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Destroy(bool have_context);
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Creates a Buffer for the given buffer.
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void CreateBuffer(GLuint client_id, GLuint service_id);
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Gets the buffer info for the given buffer.
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Buffer* GetBuffer(GLuint client_id);
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Removes a buffer info for the given buffer.
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void RemoveBuffer(GLuint client_id);
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Gets a client id for a given service id.
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool GetClientId(GLuint service_id, GLuint* client_id) const;
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1969ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  // Validates a glBufferSubData, and then calls DoBufferData if validation was
1979ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  // successful.
1989ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  void ValidateAndDoBufferSubData(
1999ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch      ContextState* context_state, GLenum target, GLintptr offset,
2009ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch      GLsizeiptr size, const GLvoid * data);
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2029ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  // Validates a glBufferData, and then calls DoBufferData if validation was
2039ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  // successful.
2049ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  void ValidateAndDoBufferData(
2059ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch    ContextState* context_state, GLenum target, GLsizeiptr size,
2069ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch    const GLvoid * data, GLenum usage);
2079ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch
2089ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  // Validates a glGetBufferParameteriv, and then calls GetBufferParameteriv if
2099ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  // validation was successful.
2109ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  void ValidateAndDoGetBufferParameteriv(
2119ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch    ContextState* context_state, GLenum target, GLenum pname, GLint* params);
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sets the target of a buffer. Returns false if the target can not be set.
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool SetTarget(Buffer* buffer, GLenum target);
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_allow_buffers_on_multiple_targets(bool allow) {
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    allow_buffers_on_multiple_targets_ = allow;
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t mem_represented() const {
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return memory_tracker_->GetMemRepresented();
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
224868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Tells for a given usage if this would be a client side array.
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool IsUsageClientSideArray(GLenum usage);
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
227868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Tells whether a buffer that is emulated using client-side arrays should be
228868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // set to a non-zero size.
229868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  bool UseNonZeroSizeForClientSideArrayBuffer();
230868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  friend class Buffer;
2339ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  friend class TestHelper;  // Needs access to DoBufferData.
2349ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  friend class BufferManagerTestBase;  // Needs access to DoBufferSubData.
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void StartTracking(Buffer* buffer);
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void StopTracking(Buffer* buffer);
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2389ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  Buffer* GetBufferInfoForTarget(ContextState* state, GLenum target);
2399ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch
2409ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  // Does a glBufferSubData and updates the approriate accounting.
2419ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  // Assumes the values have already been validated.
2429ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  void DoBufferSubData(
2439ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch      ErrorState* error_state,
2449ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch      Buffer* buffer,
2459ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch      GLintptr offset,
2469ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch      GLsizeiptr size,
2479ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch      const GLvoid* data);
2489ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch
2499ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  // Does a glBufferData and updates the approprate accounting. Currently
2509ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  // Assumes the values have already been validated.
2519ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  void DoBufferData(
2529ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch      ErrorState* error_state,
2539ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch      Buffer* buffer,
2549ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch      GLsizeiptr size,
2559ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch      GLenum usage,
2569ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch      const GLvoid* data);
2579ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Sets the size, usage and initial data of a buffer.
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If data is NULL buffer will be initialized to 0 if shadowed.
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void SetInfo(
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Buffer* buffer, GLsizeiptr size, GLenum usage, const GLvoid* data);
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<MemoryTypeTracker> memory_tracker_;
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FeatureInfo> feature_info_;
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Info for each buffer in the system.
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  typedef base::hash_map<GLuint, scoped_refptr<Buffer> > BufferMap;
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BufferMap buffers_;
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Whether or not buffers can be bound to multiple targets.
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool allow_buffers_on_multiple_targets_;
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Counts the number of Buffer allocated with 'this' as its manager.
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Allows to check no Buffer will outlive this.
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  unsigned int buffer_count_;
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool have_context_;
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool use_client_side_arrays_for_stream_buffers_;
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(BufferManager);
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace gles2
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace gpu
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // GPU_COMMAND_BUFFER_SERVICE_BUFFER_MANAGER_H_
287