Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(108)

Unified Diff: gpu/command_buffer/service/gles2_cmd_decoder.cc

Issue 12017032: Add calls to EnsureGPUMemoryAvailable into GLES2DecoderImpl (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « gpu/command_buffer/common/gles2_cmd_utils.cc ('k') | gpu/command_buffer/service/memory_tracking.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: gpu/command_buffer/service/gles2_cmd_decoder.cc
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 1379f29cfa93bf23af1b3c3d83032ca21cb13f8a..987709406af0f3122c248409002a7ef4227e40cb 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -659,6 +659,10 @@ class GLES2DecoderImpl : public GLES2Decoder {
return vertex_array_manager_.get();
}
+ MemoryTracker* memory_tracker() {
+ return group_->memory_tracker();
+ }
+
bool IsOffscreenBufferMultisampled() const {
return offscreen_target_samples_ > 1;
}
@@ -1826,7 +1830,7 @@ ScopedTextureUploadTimer::~ScopedTextureUploadTimer() {
Texture::Texture(GLES2DecoderImpl* decoder)
: decoder_(decoder),
- memory_tracker_(decoder->GetContextGroup()->memory_tracker(),
+ memory_tracker_(decoder->memory_tracker(),
MemoryTracker::kUnmanaged),
bytes_allocated_(0),
id_(0) {
@@ -1928,7 +1932,7 @@ void Texture::Invalidate() {
RenderBuffer::RenderBuffer(GLES2DecoderImpl* decoder)
: decoder_(decoder),
- memory_tracker_(decoder->GetContextGroup()->memory_tracker(),
+ memory_tracker_(decoder->memory_tracker(),
MemoryTracker::kUnmanaged),
bytes_allocated_(0),
id_(0) {
@@ -4782,20 +4786,20 @@ void GLES2DecoderImpl::DoRenderbufferStorageMultisample(
GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
if (!renderbuffer) {
SetGLError(GL_INVALID_OPERATION,
- "glGetRenderbufferStorageMultisample", "no renderbuffer bound");
+ "glRenderbufferStorageMultisampleEXT", "no renderbuffer bound");
return;
}
if (samples > renderbuffer_manager()->max_samples()) {
SetGLError(GL_INVALID_VALUE,
- "glGetRenderbufferStorageMultisample", "samples too large");
+ "glRenderbufferStorageMultisampleEXT", "samples too large");
return;
}
if (width > renderbuffer_manager()->max_renderbuffer_size() ||
height > renderbuffer_manager()->max_renderbuffer_size()) {
SetGLError(GL_INVALID_VALUE,
- "glGetRenderbufferStorageMultisample", "size too large");
+ "glRenderbufferStorageMultisample", "dimensions too large");
return;
}
@@ -4815,6 +4819,20 @@ void GLES2DecoderImpl::DoRenderbufferStorageMultisample(
}
}
+ uint32 estimated_size = 0;
+ if (!GLES2Util::ComputeEstimatedRenderbufferSize(
+ width, height, samples, impl_format, &estimated_size)) {
+ SetGLError(GL_OUT_OF_MEMORY,
+ "glRenderbufferStorageMultsampleEXT", "dimensions too large");
+ return;
+ }
+
+ if (!memory_tracker()->EnsureGPUMemoryAvailable(estimated_size)) {
+ SetGLError(GL_OUT_OF_MEMORY,
+ "glRenderbufferStorageMultsampleEXT", "out of memory");
+ return;
+ }
+
CopyRealGLErrorsToWrapper();
if (IsAngle()) {
glRenderbufferStorageMultisampleANGLE(
@@ -4839,14 +4857,14 @@ void GLES2DecoderImpl::DoRenderbufferStorage(
GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
if (!renderbuffer) {
SetGLError(GL_INVALID_OPERATION,
- "glGetRenderbufferStorage", "no renderbuffer bound");
+ "glRenderbufferStorage", "no renderbuffer bound");
return;
}
if (width > renderbuffer_manager()->max_renderbuffer_size() ||
height > renderbuffer_manager()->max_renderbuffer_size()) {
SetGLError(GL_INVALID_VALUE,
- "glGetRenderbufferStorage", "size too large");
+ "glRenderbufferStorage", "dimensions too large");
return;
}
@@ -4866,6 +4884,19 @@ void GLES2DecoderImpl::DoRenderbufferStorage(
}
}
+ uint32 estimated_size = 0;
+ if (!GLES2Util::ComputeEstimatedRenderbufferSize(
+ width, height, 1, impl_format, &estimated_size)) {
+ SetGLError(GL_OUT_OF_MEMORY, "glRenderbufferStorage",
+ "dimensions too large");
+ return;
+ }
+
+ if (!memory_tracker()->EnsureGPUMemoryAvailable(estimated_size)) {
+ SetGLError(GL_OUT_OF_MEMORY, "glRenderbufferStorage", "out of memory");
+ return;
+ }
+
CopyRealGLErrorsToWrapper();
glRenderbufferStorageEXT(target, impl_format, width, height);
GLenum error = PeekGLError();
@@ -7091,6 +7122,12 @@ void GLES2DecoderImpl::DoBufferData(
SetGLError(GL_INVALID_VALUE, "glBufferData", "unknown buffer");
return;
}
+
+ if (!memory_tracker()->EnsureGPUMemoryAvailable(size)) {
+ SetGLError(GL_OUT_OF_MEMORY, "glBufferData", "out of memory");
+ return;
+ }
+
// Clear the buffer to 0 if no initial data was passed in.
scoped_array<int8> zero;
if (!data) {
@@ -7442,6 +7479,11 @@ error::Error GLES2DecoderImpl::DoCompressedTexImage2D(
return error::kNoError;
}
+ if (!memory_tracker()->EnsureGPUMemoryAvailable(image_size)) {
+ SetGLError(GL_OUT_OF_MEMORY, "glCompressedTexImage2D", "out of memory");
+ return error::kNoError;
+ }
+
if (info->IsAttachedToFramebuffer()) {
clear_state_dirty_ = true;
// TODO(gman): If textures tracked which framebuffers they were attached to
@@ -7676,6 +7718,12 @@ void GLES2DecoderImpl::DoTexImage2D(
width, height, border, format, type, pixels, pixels_size)) {
return;
}
+
+ if (!memory_tracker()->EnsureGPUMemoryAvailable(pixels_size)) {
+ SetGLError(GL_OUT_OF_MEMORY, "glTexImage2D", "out of memory");
+ return;
+ }
+
TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
GLsizei tex_width = 0;
GLsizei tex_height = 0;
@@ -7902,7 +7950,20 @@ void GLES2DecoderImpl::DoCopyTexImage2D(
if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
SetGLError(
GL_INVALID_OPERATION,
- "glCopyImage2D", "can not be used with depth or stencil textures");
+ "glCopyTexImage2D", "can not be used with depth or stencil textures");
+ return;
+ }
+
+ uint32 estimated_size = 0;
+ if (!GLES2Util::ComputeImageDataSizes(
+ width, height, internal_format, GL_UNSIGNED_BYTE, state_.unpack_alignment,
+ &estimated_size, NULL, NULL)) {
+ SetGLError(GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too large");
+ return;
+ }
+
+ if (!memory_tracker()->EnsureGPUMemoryAvailable(estimated_size)) {
ccameron 2013/01/19 01:38:46 So that we can take into account the current usage
+ SetGLError(GL_OUT_OF_MEMORY, "glCopyTexImage2D", "out of memory");
return;
}
@@ -9575,13 +9636,38 @@ void GLES2DecoderImpl::DoTexStorage2DEXT(
"glTexStorage2DEXT", "texture is immutable");
return;
}
+
+ GLenum format = ExtractFormatFromStorageFormat(internal_format);
+ GLenum type = ExtractTypeFromStorageFormat(internal_format);
+
+ {
+ GLsizei level_width = width;
+ GLsizei level_height = height;
+ uint32 estimated_size = 0;
+ for (int ii = 0; ii < levels; ++ii) {
+ uint32 level_size = 0;
+ if (!GLES2Util::ComputeImageDataSizes(
+ level_width, level_height, format, type, state_.unpack_alignment,
+ &estimated_size, NULL, NULL) ||
+ !SafeAddUint32(estimated_size, level_size, &estimated_size)) {
+ SetGLError(GL_OUT_OF_MEMORY,
+ "glTexStorage2DEXT", "dimensions too large");
+ return;
+ }
+ level_width = std::max(1, level_width >> 1);
+ level_height = std::max(1, level_height >> 1);
+ }
+ if (!memory_tracker()->EnsureGPUMemoryAvailable(estimated_size)) {
+ SetGLError(GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "out of memory");
+ return;
+ }
+ }
+
CopyRealGLErrorsToWrapper();
glTexStorage2DEXT(target, levels, GetTexInternalFormat(internal_format),
width, height);
GLenum error = PeekGLError();
if (error == GL_NO_ERROR) {
- GLenum format = ExtractFormatFromStorageFormat(internal_format);
- GLenum type = ExtractTypeFromStorageFormat(internal_format);
GLsizei level_width = width;
GLsizei level_height = height;
for (int ii = 0; ii < levels; ++ii) {
@@ -9883,6 +9969,11 @@ error::Error GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM(
return error::kNoError;
}
+ if (!memory_tracker()->EnsureGPUMemoryAvailable(pixels_size)) {
+ SetGLError(GL_OUT_OF_MEMORY, "glAsyncTexImage2DCHROMIUM", "out of memory");
+ return error::kNoError;
+ }
+
// We know the memory/size is safe, so get the real shared memory since
// it might need to be duped to prevent use-after-free of the memory.
Buffer buffer = GetSharedMemoryBuffer(c.pixels_shm_id);
« no previous file with comments | « gpu/command_buffer/common/gles2_cmd_utils.cc ('k') | gpu/command_buffer/service/memory_tracking.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698