| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "gpu/command_buffer/service/buffer_manager.h" | 5 #include "gpu/command_buffer/service/buffer_manager.h" |
| 6 #include <limits> | 6 #include <limits> |
| 7 #include "base/debug/trace_event.h" | 7 #include "base/debug/trace_event.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "gpu/command_buffer/common/gles2_cmd_utils.h" | 9 #include "gpu/command_buffer/common/gles2_cmd_utils.h" |
| 10 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" | 10 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" |
| (...skipping 14 matching lines...) Expand all Loading... |
| 25 DCHECK(buffer_infos_.empty()); | 25 DCHECK(buffer_infos_.empty()); |
| 26 CHECK_EQ(buffer_info_count_, 0u); | 26 CHECK_EQ(buffer_info_count_, 0u); |
| 27 } | 27 } |
| 28 | 28 |
| 29 void BufferManager::Destroy(bool have_context) { | 29 void BufferManager::Destroy(bool have_context) { |
| 30 have_context_ = have_context; | 30 have_context_ = have_context; |
| 31 buffer_infos_.clear(); | 31 buffer_infos_.clear(); |
| 32 DCHECK_EQ(0u, memory_tracker_->GetMemRepresented()); | 32 DCHECK_EQ(0u, memory_tracker_->GetMemRepresented()); |
| 33 } | 33 } |
| 34 | 34 |
| 35 void BufferManager::CreateBufferInfo(GLuint client_id, GLuint service_id) { | 35 void BufferManager::CreateBuffer(GLuint client_id, GLuint service_id) { |
| 36 BufferInfo::Ref buffer(new BufferInfo(this, service_id)); | 36 scoped_refptr<Buffer> buffer(new Buffer(this, service_id)); |
| 37 std::pair<BufferInfoMap::iterator, bool> result = | 37 std::pair<BufferInfoMap::iterator, bool> result = |
| 38 buffer_infos_.insert(std::make_pair(client_id, buffer)); | 38 buffer_infos_.insert(std::make_pair(client_id, buffer)); |
| 39 DCHECK(result.second); | 39 DCHECK(result.second); |
| 40 } | 40 } |
| 41 | 41 |
| 42 BufferManager::BufferInfo* BufferManager::GetBufferInfo( | 42 BufferManager::Buffer* BufferManager::GetBuffer( |
| 43 GLuint client_id) { | 43 GLuint client_id) { |
| 44 BufferInfoMap::iterator it = buffer_infos_.find(client_id); | 44 BufferInfoMap::iterator it = buffer_infos_.find(client_id); |
| 45 return it != buffer_infos_.end() ? it->second : NULL; | 45 return it != buffer_infos_.end() ? it->second : NULL; |
| 46 } | 46 } |
| 47 | 47 |
| 48 void BufferManager::RemoveBufferInfo(GLuint client_id) { | 48 void BufferManager::RemoveBuffer(GLuint client_id) { |
| 49 BufferInfoMap::iterator it = buffer_infos_.find(client_id); | 49 BufferInfoMap::iterator it = buffer_infos_.find(client_id); |
| 50 if (it != buffer_infos_.end()) { | 50 if (it != buffer_infos_.end()) { |
| 51 BufferInfo* buffer = it->second; | 51 Buffer* buffer = it->second; |
| 52 buffer->MarkAsDeleted(); | 52 buffer->MarkAsDeleted(); |
| 53 buffer_infos_.erase(it); | 53 buffer_infos_.erase(it); |
| 54 } | 54 } |
| 55 } | 55 } |
| 56 | 56 |
| 57 void BufferManager::StartTracking(BufferManager::BufferInfo* /* buffer */) { | 57 void BufferManager::StartTracking(BufferManager::Buffer* /* buffer */) { |
| 58 ++buffer_info_count_; | 58 ++buffer_info_count_; |
| 59 } | 59 } |
| 60 | 60 |
| 61 void BufferManager::StopTracking(BufferManager::BufferInfo* buffer) { | 61 void BufferManager::StopTracking(BufferManager::Buffer* buffer) { |
| 62 memory_tracker_->TrackMemFree(buffer->size()); | 62 memory_tracker_->TrackMemFree(buffer->size()); |
| 63 --buffer_info_count_; | 63 --buffer_info_count_; |
| 64 } | 64 } |
| 65 | 65 |
| 66 BufferManager::BufferInfo::BufferInfo(BufferManager* manager, GLuint service_id) | 66 BufferManager::Buffer::Buffer(BufferManager* manager, GLuint service_id) |
| 67 : manager_(manager), | 67 : manager_(manager), |
| 68 deleted_(false), | 68 deleted_(false), |
| 69 service_id_(service_id), | 69 service_id_(service_id), |
| 70 target_(0), | 70 target_(0), |
| 71 size_(0), | 71 size_(0), |
| 72 usage_(GL_STATIC_DRAW), | 72 usage_(GL_STATIC_DRAW), |
| 73 shadowed_(false) { | 73 shadowed_(false) { |
| 74 manager_->StartTracking(this); | 74 manager_->StartTracking(this); |
| 75 } | 75 } |
| 76 | 76 |
| 77 BufferManager::BufferInfo::~BufferInfo() { | 77 BufferManager::Buffer::~Buffer() { |
| 78 if (manager_) { | 78 if (manager_) { |
| 79 if (manager_->have_context_) { | 79 if (manager_->have_context_) { |
| 80 GLuint id = service_id(); | 80 GLuint id = service_id(); |
| 81 glDeleteBuffersARB(1, &id); | 81 glDeleteBuffersARB(1, &id); |
| 82 } | 82 } |
| 83 manager_->StopTracking(this); | 83 manager_->StopTracking(this); |
| 84 manager_ = NULL; | 84 manager_ = NULL; |
| 85 } | 85 } |
| 86 } | 86 } |
| 87 | 87 |
| 88 void BufferManager::BufferInfo::SetInfo( | 88 void BufferManager::Buffer::SetInfo( |
| 89 GLsizeiptr size, GLenum usage, bool shadow) { | 89 GLsizeiptr size, GLenum usage, bool shadow) { |
| 90 usage_ = usage; | 90 usage_ = usage; |
| 91 if (size != size_ || shadow != shadowed_) { | 91 if (size != size_ || shadow != shadowed_) { |
| 92 shadowed_ = shadow; | 92 shadowed_ = shadow; |
| 93 size_ = size; | 93 size_ = size; |
| 94 ClearCache(); | 94 ClearCache(); |
| 95 if (shadowed_) { | 95 if (shadowed_) { |
| 96 shadow_.reset(new int8[size]); | 96 shadow_.reset(new int8[size]); |
| 97 memset(shadow_.get(), 0, size); | 97 memset(shadow_.get(), 0, size); |
| 98 } | 98 } |
| 99 } | 99 } |
| 100 } | 100 } |
| 101 | 101 |
| 102 bool BufferManager::BufferInfo::CheckRange( | 102 bool BufferManager::Buffer::CheckRange( |
| 103 GLintptr offset, GLsizeiptr size) const { | 103 GLintptr offset, GLsizeiptr size) const { |
| 104 int32 end = 0; | 104 int32 end = 0; |
| 105 return offset >= 0 && size >= 0 && | 105 return offset >= 0 && size >= 0 && |
| 106 offset <= std::numeric_limits<int32>::max() && | 106 offset <= std::numeric_limits<int32>::max() && |
| 107 size <= std::numeric_limits<int32>::max() && | 107 size <= std::numeric_limits<int32>::max() && |
| 108 SafeAddInt32(offset, size, &end) && end <= size_; | 108 SafeAddInt32(offset, size, &end) && end <= size_; |
| 109 } | 109 } |
| 110 | 110 |
| 111 bool BufferManager::BufferInfo::SetRange( | 111 bool BufferManager::Buffer::SetRange( |
| 112 GLintptr offset, GLsizeiptr size, const GLvoid * data) { | 112 GLintptr offset, GLsizeiptr size, const GLvoid * data) { |
| 113 if (!CheckRange(offset, size)) { | 113 if (!CheckRange(offset, size)) { |
| 114 return false; | 114 return false; |
| 115 } | 115 } |
| 116 if (shadowed_) { | 116 if (shadowed_) { |
| 117 memcpy(shadow_.get() + offset, data, size); | 117 memcpy(shadow_.get() + offset, data, size); |
| 118 ClearCache(); | 118 ClearCache(); |
| 119 } | 119 } |
| 120 return true; | 120 return true; |
| 121 } | 121 } |
| 122 | 122 |
| 123 const void* BufferManager::BufferInfo::GetRange( | 123 const void* BufferManager::Buffer::GetRange( |
| 124 GLintptr offset, GLsizeiptr size) const { | 124 GLintptr offset, GLsizeiptr size) const { |
| 125 if (!shadowed_) { | 125 if (!shadowed_) { |
| 126 return NULL; | 126 return NULL; |
| 127 } | 127 } |
| 128 if (!CheckRange(offset, size)) { | 128 if (!CheckRange(offset, size)) { |
| 129 return NULL; | 129 return NULL; |
| 130 } | 130 } |
| 131 return shadow_.get() + offset; | 131 return shadow_.get() + offset; |
| 132 } | 132 } |
| 133 | 133 |
| 134 void BufferManager::BufferInfo::ClearCache() { | 134 void BufferManager::Buffer::ClearCache() { |
| 135 range_set_.clear(); | 135 range_set_.clear(); |
| 136 } | 136 } |
| 137 | 137 |
| 138 template <typename T> | 138 template <typename T> |
| 139 GLuint GetMaxValue(const void* data, GLuint offset, GLsizei count) { | 139 GLuint GetMaxValue(const void* data, GLuint offset, GLsizei count) { |
| 140 GLuint max_value = 0; | 140 GLuint max_value = 0; |
| 141 const T* element = reinterpret_cast<const T*>( | 141 const T* element = reinterpret_cast<const T*>( |
| 142 static_cast<const int8*>(data) + offset); | 142 static_cast<const int8*>(data) + offset); |
| 143 const T* end = element + count; | 143 const T* end = element + count; |
| 144 for (; element < end; ++element) { | 144 for (; element < end; ++element) { |
| 145 if (*element > max_value) { | 145 if (*element > max_value) { |
| 146 max_value = *element; | 146 max_value = *element; |
| 147 } | 147 } |
| 148 } | 148 } |
| 149 return max_value; | 149 return max_value; |
| 150 } | 150 } |
| 151 | 151 |
| 152 bool BufferManager::BufferInfo::GetMaxValueForRange( | 152 bool BufferManager::Buffer::GetMaxValueForRange( |
| 153 GLuint offset, GLsizei count, GLenum type, GLuint* max_value) { | 153 GLuint offset, GLsizei count, GLenum type, GLuint* max_value) { |
| 154 Range range(offset, count, type); | 154 Range range(offset, count, type); |
| 155 RangeToMaxValueMap::iterator it = range_set_.find(range); | 155 RangeToMaxValueMap::iterator it = range_set_.find(range); |
| 156 if (it != range_set_.end()) { | 156 if (it != range_set_.end()) { |
| 157 *max_value = it->second; | 157 *max_value = it->second; |
| 158 return true; | 158 return true; |
| 159 } | 159 } |
| 160 | 160 |
| 161 uint32 size; | 161 uint32 size; |
| 162 if (!SafeMultiplyUint32( | 162 if (!SafeMultiplyUint32( |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 211 it != buffer_infos_.end(); ++it) { | 211 it != buffer_infos_.end(); ++it) { |
| 212 if (it->second->service_id() == service_id) { | 212 if (it->second->service_id() == service_id) { |
| 213 *client_id = it->first; | 213 *client_id = it->first; |
| 214 return true; | 214 return true; |
| 215 } | 215 } |
| 216 } | 216 } |
| 217 return false; | 217 return false; |
| 218 } | 218 } |
| 219 | 219 |
| 220 void BufferManager::SetInfo( | 220 void BufferManager::SetInfo( |
| 221 BufferManager::BufferInfo* info, GLsizeiptr size, GLenum usage) { | 221 BufferManager::Buffer* info, GLsizeiptr size, GLenum usage) { |
| 222 DCHECK(info); | 222 DCHECK(info); |
| 223 memory_tracker_->TrackMemFree(info->size()); | 223 memory_tracker_->TrackMemFree(info->size()); |
| 224 info->SetInfo(size, | 224 info->SetInfo(size, |
| 225 usage, | 225 usage, |
| 226 info->target() == GL_ELEMENT_ARRAY_BUFFER || | 226 info->target() == GL_ELEMENT_ARRAY_BUFFER || |
| 227 allow_buffers_on_multiple_targets_); | 227 allow_buffers_on_multiple_targets_); |
| 228 memory_tracker_->TrackMemAlloc(info->size()); | 228 memory_tracker_->TrackMemAlloc(info->size()); |
| 229 } | 229 } |
| 230 | 230 |
| 231 bool BufferManager::SetTarget(BufferManager::BufferInfo* info, GLenum target) { | 231 bool BufferManager::SetTarget(BufferManager::Buffer* info, GLenum target) { |
| 232 // Check that we are not trying to bind it to a different target. | 232 // Check that we are not trying to bind it to a different target. |
| 233 if (info->target() != 0 && info->target() != target && | 233 if (info->target() != 0 && info->target() != target && |
| 234 !allow_buffers_on_multiple_targets_) { | 234 !allow_buffers_on_multiple_targets_) { |
| 235 return false; | 235 return false; |
| 236 } | 236 } |
| 237 if (info->target() == 0) { | 237 if (info->target() == 0) { |
| 238 info->set_target(target); | 238 info->set_target(target); |
| 239 } | 239 } |
| 240 return true; | 240 return true; |
| 241 } | 241 } |
| 242 | 242 |
| 243 } // namespace gles2 | 243 } // namespace gles2 |
| 244 } // namespace gpu | 244 } // namespace gpu |
| 245 | 245 |
| 246 | 246 |
| OLD | NEW |