summaryrefslogtreecommitdiffstats
path: root/chromium/gpu/command_buffer/client/gles2_implementation.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/gpu/command_buffer/client/gles2_implementation.cc')
-rw-r--r--chromium/gpu/command_buffer/client/gles2_implementation.cc640
1 files changed, 446 insertions, 194 deletions
diff --git a/chromium/gpu/command_buffer/client/gles2_implementation.cc b/chromium/gpu/command_buffer/client/gles2_implementation.cc
index b0efc3769da..716fb55fbc2 100644
--- a/chromium/gpu/command_buffer/client/gles2_implementation.cc
+++ b/chromium/gpu/command_buffer/client/gles2_implementation.cc
@@ -6,23 +6,24 @@
#include "gpu/command_buffer/client/gles2_implementation.h"
+#include <GLES2/gl2ext.h>
+#include <GLES2/gl2extchromium.h>
#include <algorithm>
+#include <limits>
#include <map>
#include <queue>
#include <set>
-#include <limits>
-#include <stdio.h>
-#include <string.h>
-#include <GLES2/gl2ext.h>
-#include <GLES2/gl2extchromium.h>
+#include <sstream>
+#include <string>
+#include "base/bind.h"
#include "gpu/command_buffer/client/buffer_tracker.h"
+#include "gpu/command_buffer/client/gpu_control.h"
#include "gpu/command_buffer/client/gpu_memory_buffer_tracker.h"
#include "gpu/command_buffer/client/program_info_manager.h"
#include "gpu/command_buffer/client/query_tracker.h"
#include "gpu/command_buffer/client/transfer_buffer.h"
#include "gpu/command_buffer/client/vertex_array_object_manager.h"
#include "gpu/command_buffer/common/gles2_cmd_utils.h"
-#include "gpu/command_buffer/common/gpu_control.h"
#include "gpu/command_buffer/common/trace_event.h"
#include "ui/gfx/gpu_memory_buffer.h"
@@ -31,8 +32,8 @@
#endif
#if defined(GPU_CLIENT_DEBUG)
-#include "ui/gl/gl_switches.h"
#include "base/command_line.h"
+#include "ui/gl/gl_switches.h"
#endif
namespace gpu {
@@ -66,8 +67,8 @@ GLES2Implementation::GLStaticState::IntState::IntState()
max_vertex_texture_image_units(0),
max_vertex_uniform_vectors(0),
num_compressed_texture_formats(0),
- num_shader_binary_formats(0) {
-}
+ num_shader_binary_formats(0),
+ bind_generates_resource_chromium(0) {}
GLES2Implementation::SingleThreadChecker::SingleThreadChecker(
GLES2Implementation* gles2_implementation)
@@ -82,12 +83,12 @@ GLES2Implementation::SingleThreadChecker::~SingleThreadChecker() {
}
GLES2Implementation::GLES2Implementation(
- GLES2CmdHelper* helper,
- ShareGroup* share_group,
- TransferBufferInterface* transfer_buffer,
- bool bind_generates_resource,
- bool free_everything_when_invisible,
- GpuControl* gpu_control)
+ GLES2CmdHelper* helper,
+ ShareGroup* share_group,
+ TransferBufferInterface* transfer_buffer,
+ bool bind_generates_resource,
+ bool lose_context_when_out_of_memory,
+ GpuControl* gpu_control)
: helper_(helper),
transfer_buffer_(transfer_buffer),
angle_pack_reverse_row_order_status_(kUnknownExtensionStatus),
@@ -107,23 +108,25 @@ GLES2Implementation::GLES2Implementation(
bound_array_buffer_id_(0),
bound_pixel_pack_transfer_buffer_id_(0),
bound_pixel_unpack_transfer_buffer_id_(0),
+ async_upload_token_(0),
+ async_upload_sync_(NULL),
+ async_upload_sync_shm_id_(0),
+ async_upload_sync_shm_offset_(0),
error_bits_(0),
debug_(false),
+ lose_context_when_out_of_memory_(lose_context_when_out_of_memory),
use_count_(0),
- current_query_(NULL),
error_message_callback_(NULL),
gpu_control_(gpu_control),
- surface_visible_(true),
- free_everything_when_invisible_(free_everything_when_invisible),
capabilities_(gpu_control->GetCapabilities()),
weak_ptr_factory_(this) {
DCHECK(helper);
DCHECK(transfer_buffer);
DCHECK(gpu_control);
- char temp[128];
- sprintf(temp, "%p", static_cast<void*>(this));
- this_in_hex_ = std::string(temp);
+ std::stringstream ss;
+ ss << std::hex << this;
+ this_in_hex_ = ss.str();
GPU_CLIENT_LOG_CODE_BLOCK({
debug_ = CommandLine::ForCurrentProcess()->HasSwitch(
@@ -141,6 +144,7 @@ bool GLES2Implementation::Initialize(
unsigned int min_transfer_buffer_size,
unsigned int max_transfer_buffer_size,
unsigned int mapped_memory_limit) {
+ TRACE_EVENT0("gpu", "GLES2Implementation::Initialize");
DCHECK_GE(starting_transfer_buffer_size, min_transfer_buffer_size);
DCHECK_LE(starting_transfer_buffer_size, max_transfer_buffer_size);
DCHECK_GE(min_transfer_buffer_size, kStartingOffset);
@@ -155,7 +159,15 @@ bool GLES2Implementation::Initialize(
return false;
}
- mapped_memory_.reset(new MappedMemoryManager(helper_, mapped_memory_limit));
+ mapped_memory_.reset(
+ new MappedMemoryManager(
+ helper_,
+ base::Bind(&GLES2Implementation::PollAsyncUploads,
+ // The mapped memory manager is owned by |this| here, and
+ // since its destroyed before before we destroy ourselves
+ // we don't need extra safety measures for this closure.
+ base::Unretained(this)),
+ mapped_memory_limit));
unsigned chunk_size = 2 * 1024 * 1024;
if (mapped_memory_limit != kNoLimit) {
@@ -190,10 +202,21 @@ bool GLES2Implementation::Initialize(
reserved_ids_[0],
reserved_ids_[1]));
+ // GL_BIND_GENERATES_RESOURCE_CHROMIUM state must be the same
+ // on Client & Service.
+ if (static_state_.int_state.bind_generates_resource_chromium !=
+ (share_group_->bind_generates_resource() ? 1 : 0)) {
+ SetGLError(GL_INVALID_OPERATION,
+ "Initialize",
+ "Service bind_generates_resource mismatch.");
+ return false;
+ }
+
return true;
}
bool GLES2Implementation::QueryAndCacheStaticState() {
+ TRACE_EVENT0("gpu", "GLES2Implementation::QueryAndCacheStaticState");
// Setup query for multiple GetIntegerv's
static const GLenum pnames[] = {
GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS,
@@ -208,6 +231,7 @@ bool GLES2Implementation::QueryAndCacheStaticState() {
GL_MAX_VERTEX_UNIFORM_VECTORS,
GL_NUM_COMPRESSED_TEXTURE_FORMATS,
GL_NUM_SHADER_BINARY_FORMATS,
+ GL_BIND_GENERATES_RESOURCE_CHROMIUM,
};
GetMultipleIntegervState integerv_state(
@@ -276,8 +300,19 @@ GLES2Implementation::~GLES2Implementation() {
#if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
DeleteBuffers(arraysize(reserved_ids_), &reserved_ids_[0]);
#endif
+
+ // Release any per-context data in share group.
+ share_group_->FreeContext(this);
+
buffer_tracker_.reset();
+ FreeAllAsyncUploadBuffers();
+
+ if (async_upload_sync_) {
+ mapped_memory_->Free(async_upload_sync_);
+ async_upload_sync_ = NULL;
+ }
+
// Make sure the commands make it the service.
WaitForCmd();
}
@@ -307,6 +342,7 @@ void GLES2Implementation::FreeUnusedSharedMemory() {
}
void GLES2Implementation::FreeEverything() {
+ FreeAllAsyncUploadBuffers();
WaitForCmd();
query_tracker_->Shrink();
FreeUnusedSharedMemory();
@@ -341,19 +377,15 @@ void GLES2Implementation::SignalQuery(uint32 query,
}
void GLES2Implementation::SetSurfaceVisible(bool visible) {
+ TRACE_EVENT1(
+ "gpu", "GLES2Implementation::SetSurfaceVisible", "visible", visible);
// TODO(piman): This probably should be ShallowFlushCHROMIUM().
Flush();
- surface_visible_ = visible;
gpu_control_->SetSurfaceVisible(visible);
if (!visible)
FreeEverything();
}
-void GLES2Implementation::SendManagedMemoryStats(
- const ManagedMemoryStats& stats) {
- gpu_control_->SendManagedMemoryStats(stats);
-}
-
void GLES2Implementation::WaitForCmd() {
TRACE_EVENT0("gpu", "GLES2::WaitForCmd");
helper_->CommandBufferHelper::Finish();
@@ -484,6 +516,11 @@ void GLES2Implementation::SetGLError(
error_message_callback_->OnErrorMessage(temp.c_str(), 0);
}
error_bits_ |= GLES2Util::GLErrorToErrorBit(error);
+
+ if (error == GL_OUT_OF_MEMORY && lose_context_when_out_of_memory_) {
+ helper_->LoseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB,
+ GL_UNKNOWN_CONTEXT_RESET_ARB);
+ }
}
void GLES2Implementation::SetGLErrorInvalidEnum(
@@ -827,6 +864,10 @@ void GLES2Implementation::DrawElements(
if (count == 0) {
return;
}
+ if (vertex_array_object_manager_->bound_element_array_buffer() != 0 &&
+ !ValidateOffset("glDrawElements", reinterpret_cast<GLintptr>(indices))) {
+ return;
+ }
GLuint offset = 0;
bool simulated = false;
if (!vertex_array_object_manager_->SetupSimulatedIndexAndClientSideBuffers(
@@ -847,8 +888,6 @@ void GLES2Implementation::Flush() {
// Flush our command buffer
// (tell the service to execute up to the flush cmd.)
helper_->CommandBufferHelper::Flush();
- if (!surface_visible_ && free_everything_when_invisible_)
- FreeEverything();
}
void GLES2Implementation::ShallowFlushCHROMIUM() {
@@ -863,27 +902,16 @@ void GLES2Implementation::ShallowFlushCHROMIUM() {
void GLES2Implementation::Finish() {
GPU_CLIENT_SINGLE_THREAD_CHECK();
FinishHelper();
- if (!surface_visible_ && free_everything_when_invisible_)
- FreeEverything();
}
void GLES2Implementation::ShallowFinishCHROMIUM() {
GPU_CLIENT_SINGLE_THREAD_CHECK();
+ TRACE_EVENT0("gpu", "GLES2::ShallowFinishCHROMIUM");
// Flush our command buffer (tell the service to execute up to the flush cmd
// and don't return until it completes).
helper_->CommandBufferHelper::Finish();
}
-bool GLES2Implementation::MustBeContextLost() {
- bool context_lost = helper_->IsContextLost();
- if (!context_lost) {
- WaitForCmd();
- context_lost = helper_->IsContextLost();
- }
- CHECK(context_lost);
- return context_lost;
-}
-
void GLES2Implementation::FinishHelper() {
GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glFinish()");
TRACE_EVENT0("gpu", "GLES2::Finish");
@@ -1090,14 +1118,14 @@ void GLES2Implementation::DeleteShaderStub(
GLint GLES2Implementation::GetAttribLocationHelper(
GLuint program, const char* name) {
- typedef cmds::GetAttribLocationBucket::Result Result;
+ typedef cmds::GetAttribLocation::Result Result;
Result* result = GetResultAs<Result*>();
if (!result) {
return -1;
}
*result = -1;
SetBucketAsCString(kResultBucketId, name);
- helper_->GetAttribLocationBucket(
+ helper_->GetAttribLocation(
program, kResultBucketId, GetResultShmId(), GetResultShmOffset());
WaitForCmd();
helper_->SetBucketSize(kResultBucketId, 0);
@@ -1119,14 +1147,14 @@ GLint GLES2Implementation::GetAttribLocation(
GLint GLES2Implementation::GetUniformLocationHelper(
GLuint program, const char* name) {
- typedef cmds::GetUniformLocationBucket::Result Result;
+ typedef cmds::GetUniformLocation::Result Result;
Result* result = GetResultAs<Result*>();
if (!result) {
return -1;
}
*result = -1;
SetBucketAsCString(kResultBucketId, name);
- helper_->GetUniformLocationBucket(program, kResultBucketId,
+ helper_->GetUniformLocation(program, kResultBucketId,
GetResultShmId(), GetResultShmOffset());
WaitForCmd();
helper_->SetBucketSize(kResultBucketId, 0);
@@ -1146,16 +1174,6 @@ GLint GLES2Implementation::GetUniformLocation(
return loc;
}
-void GLES2Implementation::UseProgram(GLuint program) {
- GPU_CLIENT_SINGLE_THREAD_CHECK();
- GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUseProgram(" << program << ")");
- if (current_program_ != program) {
- current_program_ = program;
- helper_->UseProgram(program);
- }
- CheckGLError();
-}
-
bool GLES2Implementation::GetProgramivHelper(
GLuint program, GLenum pname, GLint* params) {
bool got_value = share_group_->program_info_manager()->GetProgramiv(
@@ -1228,13 +1246,13 @@ void GLES2Implementation::PixelStorei(GLenum pname, GLint param) {
case GL_UNPACK_ALIGNMENT:
unpack_alignment_ = param;
break;
- case GL_UNPACK_ROW_LENGTH:
+ case GL_UNPACK_ROW_LENGTH_EXT:
unpack_row_length_ = param;
return;
- case GL_UNPACK_SKIP_ROWS:
+ case GL_UNPACK_SKIP_ROWS_EXT:
unpack_skip_rows_ = param;
return;
- case GL_UNPACK_SKIP_PIXELS:
+ case GL_UNPACK_SKIP_PIXELS_EXT:
unpack_skip_pixels_ = param;
return;
case GL_UNPACK_FLIP_Y_CHROMIUM:
@@ -1251,7 +1269,6 @@ void GLES2Implementation::PixelStorei(GLenum pname, GLint param) {
CheckGLError();
}
-
void GLES2Implementation::VertexAttribPointer(
GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride,
const void* ptr) {
@@ -1273,10 +1290,18 @@ void GLES2Implementation::VertexAttribPointer(
#if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
if (bound_array_buffer_id_ != 0) {
// Only report NON client side buffers to the service.
+ if (!ValidateOffset("glVertexAttribPointer",
+ reinterpret_cast<GLintptr>(ptr))) {
+ return;
+ }
helper_->VertexAttribPointer(index, size, type, normalized, stride,
ToGLuint(ptr));
}
#else // !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
+ if (!ValidateOffset("glVertexAttribPointer",
+ reinterpret_cast<GLintptr>(ptr))) {
+ return;
+ }
helper_->VertexAttribPointer(index, size, type, normalized, stride,
ToGLuint(ptr));
#endif // !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
@@ -1366,10 +1391,8 @@ void GLES2Implementation::ShaderSource(
void GLES2Implementation::BufferDataHelper(
GLenum target, GLsizeiptr size, const void* data, GLenum usage) {
- if (size < 0) {
- SetGLError(GL_INVALID_VALUE, "glBufferData", "size < 0");
+ if (!ValidateSize("glBufferData", size))
return;
- }
GLuint buffer_id;
if (GetBoundPixelTransferBuffer(target, "glBufferData", &buffer_id)) {
@@ -1378,13 +1401,8 @@ void GLES2Implementation::BufferDataHelper(
}
BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffer_id);
- if (buffer) {
- // Free buffer memory, pending the passage of a token.
- buffer_tracker_->FreePendingToken(buffer, helper_->InsertToken());
-
- // Remove old buffer.
- buffer_tracker_->RemoveBuffer(buffer_id);
- }
+ if (buffer)
+ RemoveTransferBuffer(buffer);
// Create new buffer.
buffer = buffer_tracker_->CreateBuffer(buffer_id, size);
@@ -1445,8 +1463,8 @@ void GLES2Implementation::BufferSubDataHelper(
return;
}
- if (size < 0) {
- SetGLError(GL_INVALID_VALUE, "glBufferSubData", "size < 0");
+ if (!ValidateSize("glBufferSubData", size) ||
+ !ValidateOffset("glBufferSubData", offset)) {
return;
}
@@ -1512,6 +1530,30 @@ void GLES2Implementation::BufferSubData(
CheckGLError();
}
+void GLES2Implementation::RemoveTransferBuffer(BufferTracker::Buffer* buffer) {
+ int32 token = buffer->last_usage_token();
+ uint32 async_token = buffer->last_async_upload_token();
+
+ if (async_token) {
+ if (HasAsyncUploadTokenPassed(async_token)) {
+ buffer_tracker_->Free(buffer);
+ } else {
+ detached_async_upload_memory_.push_back(
+ std::make_pair(buffer->address(), async_token));
+ buffer_tracker_->Unmanage(buffer);
+ }
+ } else if (token) {
+ if (helper_->HasTokenPassed(token))
+ buffer_tracker_->Free(buffer);
+ else
+ buffer_tracker_->FreePendingToken(buffer, token);
+ } else {
+ buffer_tracker_->Free(buffer);
+ }
+
+ buffer_tracker_->RemoveBuffer(buffer->id());
+}
+
bool GLES2Implementation::GetBoundPixelTransferBuffer(
GLenum target,
const char* function_name,
@@ -1573,6 +1615,10 @@ void GLES2Implementation::CompressedTexImage2D(
SetGLError(GL_INVALID_VALUE, "glCompressedTexImage2D", "dimension < 0");
return;
}
+ if (border != 0) {
+ SetGLError(GL_INVALID_VALUE, "glCompressedTexImage2D", "border != 0");
+ return;
+ }
if (height == 0 || width == 0) {
return;
}
@@ -1585,15 +1631,15 @@ void GLES2Implementation::CompressedTexImage2D(
"glCompressedTexImage2D", offset, image_size);
if (buffer && buffer->shm_id() != -1) {
helper_->CompressedTexImage2D(
- target, level, internalformat, width, height, border, image_size,
+ target, level, internalformat, width, height, image_size,
buffer->shm_id(), buffer->shm_offset() + offset);
- buffer->set_transfer_ready_token(helper_->InsertToken());
+ buffer->set_last_usage_token(helper_->InsertToken());
}
return;
}
SetBucketContents(kResultBucketId, data, image_size);
helper_->CompressedTexImage2DBucket(
- target, level, internalformat, width, height, border, kResultBucketId);
+ target, level, internalformat, width, height, kResultBucketId);
// Free the bucket. This is not required but it does free up the memory.
// and we don't have to wait for the result so from the client's perspective
// it's cheap.
@@ -1628,7 +1674,7 @@ void GLES2Implementation::CompressedTexSubImage2D(
helper_->CompressedTexSubImage2D(
target, level, xoffset, yoffset, width, height, format, image_size,
buffer->shm_id(), buffer->shm_offset() + offset);
- buffer->set_transfer_ready_token(helper_->InsertToken());
+ buffer->set_last_usage_token(helper_->InsertToken());
CheckGLError();
}
return;
@@ -1695,6 +1741,10 @@ void GLES2Implementation::TexImage2D(
SetGLError(GL_INVALID_VALUE, "glTexImage2D", "dimension < 0");
return;
}
+ if (border != 0) {
+ SetGLError(GL_INVALID_VALUE, "glTexImage2D", "border != 0");
+ return;
+ }
uint32 size;
uint32 unpadded_row_size;
uint32 padded_row_size;
@@ -1713,9 +1763,9 @@ void GLES2Implementation::TexImage2D(
"glTexImage2D", offset, size);
if (buffer && buffer->shm_id() != -1) {
helper_->TexImage2D(
- target, level, internalformat, width, height, border, format, type,
+ target, level, internalformat, width, height, format, type,
buffer->shm_id(), buffer->shm_offset() + offset);
- buffer->set_transfer_ready_token(helper_->InsertToken());
+ buffer->set_last_usage_token(helper_->InsertToken());
CheckGLError();
}
return;
@@ -1724,7 +1774,7 @@ void GLES2Implementation::TexImage2D(
// If there's no data just issue TexImage2D
if (!pixels) {
helper_->TexImage2D(
- target, level, internalformat, width, height, border, format, type,
+ target, level, internalformat, width, height, format, type,
0, 0);
CheckGLError();
return;
@@ -1764,7 +1814,7 @@ void GLES2Implementation::TexImage2D(
pixels, height, unpadded_row_size, src_padded_row_size, unpack_flip_y_,
buffer.address(), padded_row_size);
helper_->TexImage2D(
- target, level, internalformat, width, height, border, format, type,
+ target, level, internalformat, width, height, format, type,
buffer.shm_id(), buffer.offset());
CheckGLError();
return;
@@ -1772,7 +1822,7 @@ void GLES2Implementation::TexImage2D(
// No, so send it using TexSubImage2D.
helper_->TexImage2D(
- target, level, internalformat, width, height, border, format, type,
+ target, level, internalformat, width, height, format, type,
0, 0);
TexSubImage2DImpl(
target, level, 0, 0, width, height, format, type, unpadded_row_size,
@@ -1821,7 +1871,7 @@ void GLES2Implementation::TexSubImage2D(
helper_->TexSubImage2D(
target, level, xoffset, yoffset, width, height, format, type,
buffer->shm_id(), buffer->shm_offset() + offset, false);
- buffer->set_transfer_ready_token(helper_->InsertToken());
+ buffer->set_last_usage_token(helper_->InsertToken());
CheckGLError();
}
return;
@@ -1859,9 +1909,9 @@ void GLES2Implementation::TexSubImage2D(
}
static GLint ComputeNumRowsThatFitInBuffer(
- GLsizeiptr padded_row_size, GLsizeiptr unpadded_row_size,
+ uint32 padded_row_size, uint32 unpadded_row_size,
unsigned int size) {
- DCHECK_GE(unpadded_row_size, 0);
+ DCHECK_GE(unpadded_row_size, 0u);
if (padded_row_size == 0) {
return 1;
}
@@ -2146,7 +2196,8 @@ const GLubyte* GLES2Implementation::GetStringHelper(GLenum name) {
case GL_EXTENSIONS:
str += std::string(str.empty() ? "" : " ") +
"GL_CHROMIUM_flipy "
- "GL_EXT_unpack_subimage";
+ "GL_EXT_unpack_subimage "
+ "GL_CHROMIUM_map_sub";
if (capabilities_.map_image) {
// The first space character is intentional.
str += " GL_CHROMIUM_map_image";
@@ -2404,24 +2455,24 @@ void GLES2Implementation::GenQueriesEXTHelper(
// deleted the resource.
bool GLES2Implementation::BindBufferHelper(
- GLenum target, GLuint buffer) {
+ GLenum target, GLuint buffer_id) {
// TODO(gman): See note #1 above.
bool changed = false;
switch (target) {
case GL_ARRAY_BUFFER:
- if (bound_array_buffer_id_ != buffer) {
- bound_array_buffer_id_ = buffer;
+ if (bound_array_buffer_id_ != buffer_id) {
+ bound_array_buffer_id_ = buffer_id;
changed = true;
}
break;
case GL_ELEMENT_ARRAY_BUFFER:
- changed = vertex_array_object_manager_->BindElementArray(buffer);
+ changed = vertex_array_object_manager_->BindElementArray(buffer_id);
break;
case GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM:
- bound_pixel_pack_transfer_buffer_id_ = buffer;
+ bound_pixel_pack_transfer_buffer_id_ = buffer_id;
break;
case GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM:
- bound_pixel_unpack_transfer_buffer_id_ = buffer;
+ bound_pixel_unpack_transfer_buffer_id_ = buffer_id;
break;
default:
changed = true;
@@ -2429,7 +2480,7 @@ bool GLES2Implementation::BindBufferHelper(
}
// TODO(gman): There's a bug here. If the target is invalid the ID will not be
// used even though it's marked it as used here.
- GetIdHandler(id_namespaces::kBuffers)->MarkAsUsedForBind(buffer);
+ GetIdHandler(id_namespaces::kBuffers)->MarkAsUsedForBind(buffer_id);
return changed;
}
@@ -2530,7 +2581,7 @@ bool GLES2Implementation::BindTextureHelper(GLenum target, GLuint texture) {
return changed;
}
-bool GLES2Implementation::BindVertexArrayHelper(GLuint array) {
+bool GLES2Implementation::BindVertexArrayOESHelper(GLuint array) {
// TODO(gman): See note #1 above.
bool changed = false;
if (!vertex_array_object_manager_->BindVertexArray(array, &changed)) {
@@ -2545,6 +2596,15 @@ bool GLES2Implementation::BindVertexArrayHelper(GLuint array) {
return changed;
}
+bool GLES2Implementation::UseProgramHelper(GLuint program) {
+ bool changed = false;
+ if (current_program_ != program) {
+ current_program_ = program;
+ changed = true;
+ }
+ return changed;
+}
+
bool GLES2Implementation::IsBufferReservedId(GLuint id) {
return vertex_array_object_manager_->IsReservedId(id);
}
@@ -2563,13 +2623,11 @@ void GLES2Implementation::DeleteBuffersHelper(
bound_array_buffer_id_ = 0;
}
vertex_array_object_manager_->UnbindBuffer(buffers[ii]);
+
BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffers[ii]);
- if (buffer) {
- // Free buffer memory, pending the passage of a token.
- buffer_tracker_->FreePendingToken(buffer, helper_->InsertToken());
- // Remove buffer.
- buffer_tracker_->RemoveBuffer(buffers[ii]);
- }
+ if (buffer)
+ RemoveTransferBuffer(buffer);
+
if (buffers[ii] == bound_pixel_unpack_transfer_buffer_id_) {
bound_pixel_unpack_transfer_buffer_id_ = 0;
}
@@ -2782,7 +2840,7 @@ void GLES2Implementation::Swap() {
weak_ptr_factory_.GetWeakPtr()));
}
-void GLES2Implementation::PartialSwapBuffers(gfx::Rect sub_buffer) {
+void GLES2Implementation::PartialSwapBuffers(const gfx::Rect& sub_buffer) {
PostSubBufferCHROMIUM(sub_buffer.x(),
sub_buffer.y(),
sub_buffer.width(),
@@ -2796,6 +2854,46 @@ void GLES2Implementation::SetSwapBuffersCompleteCallback(
swap_buffers_complete_callback_ = swap_buffers_complete_callback;
}
+static GLenum GetGLESOverlayTransform(gfx::OverlayTransform plane_transform) {
+ switch (plane_transform) {
+ case gfx::OVERLAY_TRANSFORM_INVALID:
+ break;
+ case gfx::OVERLAY_TRANSFORM_NONE:
+ return GL_OVERLAY_TRANSFORM_NONE_CHROMIUM;
+ case gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL:
+ return GL_OVERLAY_TRANSFORM_FLIP_HORIZONTAL_CHROMIUM;
+ case gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL:
+ return GL_OVERLAY_TRANSFORM_FLIP_VERTICAL_CHROMIUM;
+ case gfx::OVERLAY_TRANSFORM_ROTATE_90:
+ return GL_OVERLAY_TRANSFORM_ROTATE_90_CHROMIUM;
+ case gfx::OVERLAY_TRANSFORM_ROTATE_180:
+ return GL_OVERLAY_TRANSFORM_ROTATE_180_CHROMIUM;
+ case gfx::OVERLAY_TRANSFORM_ROTATE_270:
+ return GL_OVERLAY_TRANSFORM_ROTATE_270_CHROMIUM;
+ }
+ NOTREACHED();
+ return GL_OVERLAY_TRANSFORM_NONE_CHROMIUM;
+}
+
+void GLES2Implementation::ScheduleOverlayPlane(
+ int plane_z_order,
+ gfx::OverlayTransform plane_transform,
+ unsigned overlay_texture_id,
+ const gfx::Rect& display_bounds,
+ const gfx::RectF& uv_rect) {
+ ScheduleOverlayPlaneCHROMIUM(plane_z_order,
+ GetGLESOverlayTransform(plane_transform),
+ overlay_texture_id,
+ display_bounds.x(),
+ display_bounds.y(),
+ display_bounds.width(),
+ display_bounds.height(),
+ uv_rect.x(),
+ uv_rect.y(),
+ uv_rect.width(),
+ uv_rect.height());
+}
+
void GLES2Implementation::OnSwapBuffersComplete() {
if (!swap_buffers_complete_callback_.is_null())
swap_buffers_complete_callback_.Run();
@@ -2835,10 +2933,11 @@ void* GLES2Implementation::MapBufferSubDataCHROMIUM(
"glMapBufferSubDataCHROMIUM", access, "access");
return NULL;
}
- if (offset < 0 || size < 0) {
- SetGLError(GL_INVALID_VALUE, "glMapBufferSubDataCHROMIUM", "bad range");
+ if (!ValidateSize("glMapBufferSubDataCHROMIUM", size) ||
+ !ValidateOffset("glMapBufferSubDataCHROMIUM", offset)) {
return NULL;
}
+
int32 shm_id;
unsigned int shm_offset;
void* mem = mapped_memory_->Alloc(size, &shm_id, &shm_offset);
@@ -3048,6 +3147,7 @@ void GLES2Implementation::GetMultipleIntegervCHROMIUM(
" " << i << ": " << GLES2Util::GetStringGLState(pnames[i]));
}
});
+ DCHECK(size >= 0 && FitInt32NonNegative<GLsizeiptr>(size));
GetMultipleIntegervState state(pnames, count, results, size);
if (!GetMultipleIntegervSetup(&state)) {
@@ -3208,29 +3308,8 @@ GLuint GLES2Implementation::CreateStreamTextureCHROMIUM(GLuint texture) {
GPU_CLIENT_LOG("[" << GetLogPrefix() << "] CreateStreamTextureCHROMIUM("
<< texture << ")");
TRACE_EVENT0("gpu", "GLES2::CreateStreamTextureCHROMIUM");
- typedef cmds::CreateStreamTextureCHROMIUM::Result Result;
- Result* result = GetResultAs<Result*>();
- if (!result) {
- return GL_ZERO;
- }
- *result = GL_ZERO;
-
- helper_->CreateStreamTextureCHROMIUM(texture,
- GetResultShmId(),
- GetResultShmOffset());
- WaitForCmd();
- GLuint result_value = *result;
- CheckGLError();
- return result_value;
-}
-
-void GLES2Implementation::DestroyStreamTextureCHROMIUM(GLuint texture) {
- GPU_CLIENT_SINGLE_THREAD_CHECK();
- GPU_CLIENT_LOG("[" << GetLogPrefix() << "] DestroyStreamTextureCHROMIUM("
- << texture << ")");
- TRACE_EVENT0("gpu", "GLES2::DestroyStreamTextureCHROMIUM");
- helper_->DestroyStreamTextureCHROMIUM(texture);
- CheckGLError();
+ helper_->CommandBufferHelper::Flush();
+ return gpu_control_->CreateStreamTexture(texture);
}
void GLES2Implementation::PostSubBufferCHROMIUM(
@@ -3290,7 +3369,8 @@ void GLES2Implementation::BeginQueryEXT(GLenum target, GLuint id) {
<< ", " << id << ")");
// if any outstanding queries INV_OP
- if (current_query_) {
+ QueryMap::iterator it = current_queries_.find(target);
+ if (it != current_queries_.end()) {
SetGLError(
GL_INVALID_OPERATION, "glBeginQueryEXT", "query already in progress");
return;
@@ -3309,7 +3389,9 @@ void GLES2Implementation::BeginQueryEXT(GLenum target, GLuint id) {
if (!query) {
query = query_tracker_->CreateQuery(id, target);
if (!query) {
- MustBeContextLost();
+ SetGLError(GL_OUT_OF_MEMORY,
+ "glBeginQueryEXT",
+ "transfer buffer allocation failed");
return;
}
} else if (query->target() != target) {
@@ -3318,7 +3400,7 @@ void GLES2Implementation::BeginQueryEXT(GLenum target, GLuint id) {
return;
}
- current_query_ = query;
+ current_queries_[target] = query;
query->Begin(this);
CheckGLError();
@@ -3333,19 +3415,15 @@ void GLES2Implementation::EndQueryEXT(GLenum target) {
return;
}
- if (!current_query_) {
+ QueryMap::iterator it = current_queries_.find(target);
+ if (it == current_queries_.end()) {
SetGLError(GL_INVALID_OPERATION, "glEndQueryEXT", "no active query");
return;
}
- if (current_query_->target() != target) {
- SetGLError(GL_INVALID_OPERATION,
- "glEndQueryEXT", "target does not match active query");
- return;
- }
-
- current_query_->End(this);
- current_query_ = NULL;
+ QueryTracker::Query* query = it->second;
+ query->End(this);
+ current_queries_.erase(it);
CheckGLError();
}
@@ -3361,8 +3439,13 @@ void GLES2Implementation::GetQueryivEXT(
SetGLErrorInvalidEnum("glGetQueryivEXT", pname, "pname");
return;
}
- *params = (current_query_ && current_query_->target() == target) ?
- current_query_->id() : 0;
+ QueryMap::iterator it = current_queries_.find(target);
+ if (it != current_queries_.end()) {
+ QueryTracker::Query* query = it->second;
+ *params = query->id();
+ } else {
+ *params = 0;
+ }
GPU_CLIENT_LOG(" " << *params);
CheckGLError();
}
@@ -3380,7 +3463,8 @@ void GLES2Implementation::GetQueryObjectuivEXT(
return;
}
- if (query == current_query_) {
+ QueryMap::iterator it = current_queries_.find(query->target());
+ if (it != current_queries_.end()) {
SetGLError(
GL_INVALID_OPERATION,
"glQueryObjectuivEXT", "query active. Did you to call glEndQueryEXT?");
@@ -3399,8 +3483,7 @@ void GLES2Implementation::GetQueryObjectuivEXT(
if (!query->CheckResultsAvailable(helper_)) {
helper_->WaitForToken(query->token());
if (!query->CheckResultsAvailable(helper_)) {
- // TODO(gman): Speed this up.
- WaitForCmd();
+ FinishHelper();
CHECK(query->CheckResultsAvailable(helper_));
}
}
@@ -3471,6 +3554,11 @@ void GLES2Implementation::DrawElementsInstancedANGLE(
if (primcount == 0) {
return;
}
+ if (vertex_array_object_manager_->bound_element_array_buffer() != 0 &&
+ !ValidateOffset("glDrawElementsInstancedANGLE",
+ reinterpret_cast<GLintptr>(indices))) {
+ return;
+ }
GLuint offset = 0;
bool simulated = false;
if (!vertex_array_object_manager_->SetupSimulatedIndexAndClientSideBuffers(
@@ -3490,12 +3578,66 @@ void GLES2Implementation::GenMailboxCHROMIUM(
<< static_cast<const void*>(mailbox) << ")");
TRACE_EVENT0("gpu", "GLES2::GenMailboxCHROMIUM");
- std::vector<gpu::Mailbox> names;
- if (!gpu_control_->GenerateMailboxNames(1, &names)) {
- SetGLError(GL_OUT_OF_MEMORY, "glGenMailboxCHROMIUM", "Generate failed.");
- return;
- }
- memcpy(mailbox, names[0].name, GL_MAILBOX_SIZE_CHROMIUM);
+ gpu::Mailbox result = gpu::Mailbox::Generate();
+ memcpy(mailbox, result.name, sizeof(result.name));
+}
+
+void GLES2Implementation::ProduceTextureCHROMIUM(GLenum target,
+ const GLbyte* data) {
+ GPU_CLIENT_SINGLE_THREAD_CHECK();
+ GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glProduceTextureCHROMIUM("
+ << static_cast<const void*>(data) << ")");
+ const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
+ DCHECK(mailbox.Verify()) << "ProduceTextureCHROMIUM was passed a "
+ "mailbox that was not generated by "
+ "GenMailboxCHROMIUM.";
+ helper_->ProduceTextureCHROMIUMImmediate(target, data);
+ CheckGLError();
+}
+
+void GLES2Implementation::ProduceTextureDirectCHROMIUM(
+ GLuint texture, GLenum target, const GLbyte* data) {
+ GPU_CLIENT_SINGLE_THREAD_CHECK();
+ GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glProduceTextureDirectCHROMIUM("
+ << static_cast<const void*>(data) << ")");
+ const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
+ DCHECK(mailbox.Verify()) << "ProduceTextureDirectCHROMIUM was passed a "
+ "mailbox that was not generated by "
+ "GenMailboxCHROMIUM.";
+ helper_->ProduceTextureDirectCHROMIUMImmediate(texture, target, data);
+ CheckGLError();
+}
+
+void GLES2Implementation::ConsumeTextureCHROMIUM(GLenum target,
+ const GLbyte* data) {
+ GPU_CLIENT_SINGLE_THREAD_CHECK();
+ GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glConsumeTextureCHROMIUM("
+ << static_cast<const void*>(data) << ")");
+ const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
+ DCHECK(mailbox.Verify()) << "ConsumeTextureCHROMIUM was passed a "
+ "mailbox that was not generated by "
+ "GenMailboxCHROMIUM.";
+ helper_->ConsumeTextureCHROMIUMImmediate(target, data);
+ CheckGLError();
+}
+
+GLuint GLES2Implementation::CreateAndConsumeTextureCHROMIUM(
+ GLenum target, const GLbyte* data) {
+ GPU_CLIENT_SINGLE_THREAD_CHECK();
+ GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glCreateAndConsumeTextureCHROMIUM("
+ << static_cast<const void*>(data) << ")");
+ const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
+ DCHECK(mailbox.Verify()) << "CreateAndConsumeTextureCHROMIUM was passed a "
+ "mailbox that was not generated by "
+ "GenMailboxCHROMIUM.";
+ GLuint client_id;
+ GetIdHandler(id_namespaces::kTextures)->MakeIds(this, 0, 1, &client_id);
+ helper_->CreateAndConsumeTextureCHROMIUMImmediate(target,
+ client_id, data);
+ if (share_group_->bind_generates_resource())
+ helper_->CommandBufferHelper::Flush();
+ CheckGLError();
+ return client_id;
}
void GLES2Implementation::PushGroupMarkerEXT(
@@ -3609,9 +3751,9 @@ void* GLES2Implementation::MapBufferCHROMIUM(GLuint target, GLenum access) {
// with this method of synchronization. Until this is fixed,
// MapBufferCHROMIUM will not block even if the transfer is not ready
// for these calls.
- if (buffer->transfer_ready_token()) {
- helper_->WaitForToken(buffer->transfer_ready_token());
- buffer->set_transfer_ready_token(0);
+ if (buffer->last_usage_token()) {
+ helper_->WaitForToken(buffer->last_usage_token());
+ buffer->set_last_usage_token(0);
}
buffer->set_mapped(true);
@@ -3645,8 +3787,73 @@ GLboolean GLES2Implementation::UnmapBufferCHROMIUM(GLuint target) {
return true;
}
+bool GLES2Implementation::EnsureAsyncUploadSync() {
+ if (async_upload_sync_)
+ return true;
+
+ int32 shm_id;
+ unsigned int shm_offset;
+ void* mem = mapped_memory_->Alloc(sizeof(AsyncUploadSync),
+ &shm_id,
+ &shm_offset);
+ if (!mem)
+ return false;
+
+ async_upload_sync_shm_id_ = shm_id;
+ async_upload_sync_shm_offset_ = shm_offset;
+ async_upload_sync_ = static_cast<AsyncUploadSync*>(mem);
+ async_upload_sync_->Reset();
+
+ return true;
+}
+
+uint32 GLES2Implementation::NextAsyncUploadToken() {
+ async_upload_token_++;
+ if (async_upload_token_ == 0)
+ async_upload_token_++;
+ return async_upload_token_;
+}
+
+void GLES2Implementation::PollAsyncUploads() {
+ if (!async_upload_sync_)
+ return;
+
+ if (helper_->IsContextLost()) {
+ DetachedAsyncUploadMemoryList::iterator it =
+ detached_async_upload_memory_.begin();
+ while (it != detached_async_upload_memory_.end()) {
+ mapped_memory_->Free(it->first);
+ it = detached_async_upload_memory_.erase(it);
+ }
+ return;
+ }
+
+ DetachedAsyncUploadMemoryList::iterator it =
+ detached_async_upload_memory_.begin();
+ while (it != detached_async_upload_memory_.end()) {
+ if (HasAsyncUploadTokenPassed(it->second)) {
+ mapped_memory_->Free(it->first);
+ it = detached_async_upload_memory_.erase(it);
+ } else {
+ break;
+ }
+ }
+}
+
+void GLES2Implementation::FreeAllAsyncUploadBuffers() {
+ // Free all completed unmanaged async uploads buffers.
+ PollAsyncUploads();
+
+ // Synchronously free rest of the unmanaged async upload buffers.
+ if (!detached_async_upload_memory_.empty()) {
+ WaitAllAsyncTexImage2DCHROMIUM();
+ WaitForCmd();
+ PollAsyncUploads();
+ }
+}
+
void GLES2Implementation::AsyncTexImage2DCHROMIUM(
- GLenum target, GLint level, GLint internalformat, GLsizei width,
+ GLenum target, GLint level, GLenum internalformat, GLsizei width,
GLsizei height, GLint border, GLenum format, GLenum type,
const void* pixels) {
GPU_CLIENT_SINGLE_THREAD_CHECK();
@@ -3662,6 +3869,10 @@ void GLES2Implementation::AsyncTexImage2DCHROMIUM(
SetGLError(GL_INVALID_VALUE, "glTexImage2D", "dimension < 0");
return;
}
+ if (border != 0) {
+ SetGLError(GL_INVALID_VALUE, "glTexImage2D", "border != 0");
+ return;
+ }
uint32 size;
uint32 unpadded_row_size;
uint32 padded_row_size;
@@ -3675,8 +3886,13 @@ void GLES2Implementation::AsyncTexImage2DCHROMIUM(
// If there's no data/buffer just issue the AsyncTexImage2D
if (!pixels && !bound_pixel_unpack_transfer_buffer_id_) {
helper_->AsyncTexImage2DCHROMIUM(
- target, level, internalformat, width, height, border, format, type,
- 0, 0);
+ target, level, internalformat, width, height, format, type,
+ 0, 0, 0, 0, 0);
+ return;
+ }
+
+ if (!EnsureAsyncUploadSync()) {
+ SetGLError(GL_OUT_OF_MEMORY, "glTexImage2D", "out of memory");
return;
}
@@ -3689,9 +3905,13 @@ void GLES2Implementation::AsyncTexImage2DCHROMIUM(
bound_pixel_unpack_transfer_buffer_id_,
"glAsyncTexImage2DCHROMIUM", offset, size);
if (buffer && buffer->shm_id() != -1) {
+ uint32 async_token = NextAsyncUploadToken();
+ buffer->set_last_async_upload_token(async_token);
helper_->AsyncTexImage2DCHROMIUM(
- target, level, internalformat, width, height, border, format, type,
- buffer->shm_id(), buffer->shm_offset() + offset);
+ target, level, internalformat, width, height, format, type,
+ buffer->shm_id(), buffer->shm_offset() + offset,
+ async_token,
+ async_upload_sync_shm_id_, async_upload_sync_shm_offset_);
}
}
@@ -3724,6 +3944,11 @@ void GLES2Implementation::AsyncTexSubImage2DCHROMIUM(
return;
}
+ if (!EnsureAsyncUploadSync()) {
+ SetGLError(GL_OUT_OF_MEMORY, "glTexImage2D", "out of memory");
+ return;
+ }
+
// Async uploads require a transfer buffer to be bound.
// TODO(hubbe): Make MapBufferCHROMIUM block if someone tries to re-use
// the buffer before the transfer is finished. (Currently such
@@ -3733,9 +3958,13 @@ void GLES2Implementation::AsyncTexSubImage2DCHROMIUM(
bound_pixel_unpack_transfer_buffer_id_,
"glAsyncTexSubImage2DCHROMIUM", offset, size);
if (buffer && buffer->shm_id() != -1) {
+ uint32 async_token = NextAsyncUploadToken();
+ buffer->set_last_async_upload_token(async_token);
helper_->AsyncTexSubImage2DCHROMIUM(
target, level, xoffset, yoffset, width, height, format, type,
- buffer->shm_id(), buffer->shm_offset() + offset);
+ buffer->shm_id(), buffer->shm_offset() + offset,
+ async_token,
+ async_upload_sync_shm_id_, async_upload_sync_shm_offset_);
}
}
@@ -3747,6 +3976,14 @@ void GLES2Implementation::WaitAsyncTexImage2DCHROMIUM(GLenum target) {
CheckGLError();
}
+void GLES2Implementation::WaitAllAsyncTexImage2DCHROMIUM() {
+ GPU_CLIENT_SINGLE_THREAD_CHECK();
+ GPU_CLIENT_LOG("[" << GetLogPrefix()
+ << "] glWaitAllAsyncTexImage2DCHROMIUM()");
+ helper_->WaitAllAsyncTexImage2DCHROMIUM();
+ CheckGLError();
+}
+
GLuint GLES2Implementation::InsertSyncPointCHROMIUM() {
GPU_CLIENT_SINGLE_THREAD_CHECK();
GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glInsertSyncPointCHROMIUM");
@@ -3754,8 +3991,10 @@ GLuint GLES2Implementation::InsertSyncPointCHROMIUM() {
return gpu_control_->InsertSyncPoint();
}
-GLuint GLES2Implementation::CreateImageCHROMIUMHelper(
- GLsizei width, GLsizei height, GLenum internalformat) {
+GLuint GLES2Implementation::CreateImageCHROMIUMHelper(GLsizei width,
+ GLsizei height,
+ GLenum internalformat,
+ GLenum usage) {
if (width <= 0) {
SetGLError(GL_INVALID_VALUE, "glCreateImageCHROMIUM", "width <= 0");
return 0;
@@ -3771,7 +4010,7 @@ GLuint GLES2Implementation::CreateImageCHROMIUMHelper(
// Create new buffer.
GLuint buffer_id = gpu_memory_buffer_tracker_->CreateBuffer(
- width, height, internalformat);
+ width, height, internalformat, usage);
if (buffer_id == 0) {
SetGLError(GL_OUT_OF_MEMORY, "glCreateImageCHROMIUM", "out of GPU memory.");
return 0;
@@ -3779,14 +4018,18 @@ GLuint GLES2Implementation::CreateImageCHROMIUMHelper(
return buffer_id;
}
-GLuint GLES2Implementation::CreateImageCHROMIUM(
- GLsizei width, GLsizei height, GLenum internalformat) {
+GLuint GLES2Implementation::CreateImageCHROMIUM(GLsizei width,
+ GLsizei height,
+ GLenum internalformat,
+ GLenum usage) {
GPU_CLIENT_SINGLE_THREAD_CHECK();
- GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glCreateImageCHROMIUM("
- << width << ", "
- << height << ", "
- << GLES2Util::GetStringTextureInternalFormat(internalformat) << ")");
- GLuint image_id = CreateImageCHROMIUMHelper(width, height, internalformat);
+ GPU_CLIENT_LOG(
+ "[" << GetLogPrefix() << "] glCreateImageCHROMIUM(" << width << ", "
+ << height << ", "
+ << GLES2Util::GetStringTextureInternalFormat(internalformat) << ", "
+ << GLES2Util::GetStringTextureInternalFormat(usage) << ")");
+ GLuint image_id =
+ CreateImageCHROMIUMHelper(width, height, internalformat, usage);
CheckGLError();
return image_id;
}
@@ -3837,49 +4080,28 @@ void GLES2Implementation::UnmapImageCHROMIUM(GLuint image_id) {
CheckGLError();
}
-void* GLES2Implementation::MapImageCHROMIUMHelper(GLuint image_id,
- GLenum access) {
+void* GLES2Implementation::MapImageCHROMIUMHelper(GLuint image_id) {
gfx::GpuMemoryBuffer* gpu_buffer = gpu_memory_buffer_tracker_->GetBuffer(
image_id);
if (!gpu_buffer) {
SetGLError(GL_INVALID_OPERATION, "glMapImageCHROMIUM", "invalid image");
return NULL;
}
- gfx::GpuMemoryBuffer::AccessMode mode;
- switch(access) {
- case GL_WRITE_ONLY:
- mode = gfx::GpuMemoryBuffer::WRITE_ONLY;
- break;
- case GL_READ_ONLY:
- mode = gfx::GpuMemoryBuffer::READ_ONLY;
- break;
- case GL_READ_WRITE:
- mode = gfx::GpuMemoryBuffer::READ_WRITE;
- break;
- default:
- SetGLError(GL_INVALID_ENUM, "glMapImageCHROMIUM",
- "invalid GPU access mode");
- return NULL;
- }
if (gpu_buffer->IsMapped()) {
SetGLError(GL_INVALID_OPERATION, "glMapImageCHROMIUM", "already mapped");
return NULL;
}
- void* mapped_buffer = NULL;
- gpu_buffer->Map(mode, &mapped_buffer);
- return mapped_buffer;
+ return gpu_buffer->Map();
}
-void* GLES2Implementation::MapImageCHROMIUM(
- GLuint image_id, GLenum access) {
+void* GLES2Implementation::MapImageCHROMIUM(GLuint image_id) {
GPU_CLIENT_SINGLE_THREAD_CHECK();
- GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glMapImageCHROMIUM("
- << image_id << ", "
- << GLES2Util::GetStringEnum(access) << ")");
+ GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glMapImageCHROMIUM(" << image_id
+ << ")");
- void* mapped = MapImageCHROMIUMHelper(image_id, access);
+ void* mapped = MapImageCHROMIUMHelper(image_id);
CheckGLError();
return mapped;
}
@@ -3900,6 +4122,12 @@ void GLES2Implementation::GetImageParameterivCHROMIUMHelper(
return;
}
+ if (!gpu_buffer->IsMapped()) {
+ SetGLError(
+ GL_INVALID_OPERATION, "glGetImageParameterivCHROMIUM", "not mapped");
+ return;
+ }
+
*params = gpu_buffer->GetStride();
}
@@ -3915,6 +4143,30 @@ void GLES2Implementation::GetImageParameterivCHROMIUM(
CheckGLError();
}
+bool GLES2Implementation::ValidateSize(const char* func, GLsizeiptr size) {
+ if (size < 0) {
+ SetGLError(GL_INVALID_VALUE, func, "size < 0");
+ return false;
+ }
+ if (!FitInt32NonNegative<GLsizeiptr>(size)) {
+ SetGLError(GL_INVALID_OPERATION, func, "size more than 32-bit");
+ return false;
+ }
+ return true;
+}
+
+bool GLES2Implementation::ValidateOffset(const char* func, GLintptr offset) {
+ if (offset < 0) {
+ SetGLError(GL_INVALID_VALUE, func, "offset < 0");
+ return false;
+ }
+ if (!FitInt32NonNegative<GLintptr>(offset)) {
+ SetGLError(GL_INVALID_OPERATION, func, "offset more than 32-bit");
+ return false;
+ }
+ return true;
+}
+
// Include the auto-generated part of this file. We split this because it means
// we can easily edit the non-auto generated parts right here in this file
// instead of having to edit some template or the code generator.