#include <queue>
#include <set>
#include <limits>
-#include <stdio.h>
-#include <string.h>
+#include <sstream>
+#include <string>
#include <GLES2/gl2ext.h>
#include <GLES2/gl2extchromium.h>
#include "gpu/command_buffer/client/buffer_tracker.h"
GLES2Implementation::SingleThreadChecker::SingleThreadChecker(
GLES2Implementation* gles2_implementation)
: gles2_implementation_(gles2_implementation) {
- GPU_CHECK_EQ(0, gles2_implementation_->use_count_);
+ CHECK_EQ(0, gles2_implementation_->use_count_);
++gles2_implementation_->use_count_;
}
GLES2Implementation::SingleThreadChecker::~SingleThreadChecker() {
--gles2_implementation_->use_count_;
- GPU_CHECK_EQ(0, gles2_implementation_->use_count_);
+ CHECK_EQ(0, gles2_implementation_->use_count_);
}
GLES2Implementation::GLES2Implementation(
ShareGroup* share_group,
TransferBufferInterface* transfer_buffer,
bool bind_generates_resource,
+ bool free_everything_when_invisible,
GpuControl* gpu_control)
: helper_(helper),
transfer_buffer_(transfer_buffer),
error_bits_(0),
debug_(false),
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) {
- GPU_DCHECK(helper);
- GPU_DCHECK(transfer_buffer);
- GPU_DCHECK(gpu_control);
+ 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(
unsigned int min_transfer_buffer_size,
unsigned int max_transfer_buffer_size,
unsigned int mapped_memory_limit) {
- GPU_DCHECK_GE(starting_transfer_buffer_size, min_transfer_buffer_size);
- GPU_DCHECK_LE(starting_transfer_buffer_size, max_transfer_buffer_size);
- GPU_DCHECK_GE(min_transfer_buffer_size, kStartingOffset);
+ 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);
if (!transfer_buffer_->Initialize(
starting_transfer_buffer_size,
callback));
}
+void GLES2Implementation::SetSurfaceVisible(bool 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);
#if defined(GL_CLIENT_FAIL_GL_ERRORS)
void GLES2Implementation::FailGLError(GLenum error) {
if (error != GL_NO_ERROR) {
- GPU_NOTREACHED() << "Error";
+ NOTREACHED() << "Error";
}
}
// NOTE: Calling GetGLError overwrites data in the result buffer.
bool GLES2Implementation::GetBucketContents(uint32 bucket_id,
std::vector<int8>* data) {
TRACE_EVENT0("gpu", "GLES2::GetBucketContents");
- GPU_DCHECK(data);
+ DCHECK(data);
const uint32 kStartSize = 32 * 1024;
ScopedTransferBufferPtr buffer(kStartSize, helper_, transfer_buffer_);
if (!buffer.valid()) {
void GLES2Implementation::SetBucketContents(
uint32 bucket_id, const void* data, size_t size) {
- GPU_DCHECK(data);
+ DCHECK(data);
helper_->SetBucketSize(bucket_id, size);
if (size > 0u) {
uint32 offset = 0;
bool GLES2Implementation::GetBucketAsString(
uint32 bucket_id, std::string* str) {
- GPU_DCHECK(str);
+ DCHECK(str);
std::vector<int8> data;
// NOTE: strings are passed NULL terminated. That means the empty
// string will have a size of 1 and no-string will have a size of 0
// 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() {
// Flush our command buffer
// (tell the service to execute up to the flush cmd.)
helper_->CommandBufferHelper::Flush();
+ // TODO(piman): Add the FreeEverything() logic here.
}
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();
WaitForCmd();
context_lost = helper_->IsContextLost();
}
- GPU_CHECK(context_lost);
+ CHECK(context_lost);
return context_lost;
}
void GLES2Implementation::DeleteProgramStub(
GLsizei n, const GLuint* programs) {
- GPU_DCHECK_EQ(1, n);
+ DCHECK_EQ(1, n);
share_group_->program_info_manager()->DeleteInfo(programs[0]);
helper_->DeleteProgram(programs[0]);
}
void GLES2Implementation::DeleteShaderStub(
GLsizei n, const GLuint* shaders) {
- GPU_DCHECK_EQ(1, n);
+ DCHECK_EQ(1, n);
share_group_->program_info_manager()->DeleteInfo(shaders[0]);
helper_->DeleteShader(shaders[0]);
}
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:
}
}
- GPU_DCHECK_EQ(total_size, offset);
+ DCHECK_EQ(total_size, offset);
helper_->ShaderSourceBucket(shader, kResultBucketId);
helper_->SetBucketSize(kResultBucketId, 0);
// Create new buffer.
buffer = buffer_tracker_->CreateBuffer(buffer_id, size);
- GPU_DCHECK(buffer);
+ DCHECK(buffer);
if (buffer->address() && data)
memcpy(buffer->address(), data, size);
return;
void GLES2Implementation::BufferSubDataHelperImpl(
GLenum target, GLintptr offset, GLsizeiptr size, const void* data,
ScopedTransferBufferPtr* buffer) {
- GPU_DCHECK(buffer);
- GPU_DCHECK_GT(size, 0);
+ DCHECK(buffer);
+ DCHECK_GT(size, 0);
const int8* source = static_cast<const int8*>(data);
while (size) {
static GLint ComputeNumRowsThatFitInBuffer(
GLsizeiptr padded_row_size, GLsizeiptr unpadded_row_size,
unsigned int size) {
- GPU_DCHECK_GE(unpadded_row_size, 0);
+ DCHECK_GE(unpadded_row_size, 0);
if (padded_row_size == 0) {
return 1;
}
GLsizei height, GLenum format, GLenum type, uint32 unpadded_row_size,
const void* pixels, uint32 pixels_padded_row_size, GLboolean internal,
ScopedTransferBufferPtr* buffer, uint32 buffer_padded_row_size) {
- GPU_DCHECK(buffer);
- GPU_DCHECK_GE(level, 0);
- GPU_DCHECK_GT(height, 0);
- GPU_DCHECK_GT(width, 0);
+ DCHECK(buffer);
+ DCHECK_GE(level, 0);
+ DCHECK_GT(height, 0);
+ DCHECK_GT(width, 0);
const int8* source = reinterpret_cast<const int8*>(pixels);
GLint original_yoffset = yoffset;
case GL_EXTENSIONS:
str += std::string(str.empty() ? "" : " ") +
"GL_CHROMIUM_flipy "
- "GL_CHROMIUM_map_sub "
- "GL_CHROMIUM_shallow_flush "
"GL_EXT_unpack_subimage";
- if (gpu_control_->SupportsGpuMemoryBuffer()) {
+ if (capabilities_.map_image) {
// The first space character is intentional.
str += " GL_CHROMIUM_map_image";
}
std::set<std::string> strings;
std::pair<GLStringMap::iterator, bool> insert_result =
gl_strings_.insert(std::make_pair(name, strings));
- GPU_DCHECK(insert_result.second);
+ DCHECK(insert_result.second);
it = insert_result.first;
}
std::set<std::string>& string_set = it->second;
} else {
std::pair<std::set<std::string>::const_iterator, bool> insert_result =
string_set.insert(str);
- GPU_DCHECK(insert_result.second);
+ DCHECK(insert_result.second);
result = insert_result.first->c_str();
}
}
CheckGLError();
}
+void GLES2Implementation::Swap() {
+ SwapBuffers();
+ gpu_control_->Echo(
+ base::Bind(&GLES2Implementation::OnSwapBuffersComplete,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+void GLES2Implementation::PartialSwapBuffers(const gfx::Rect& sub_buffer) {
+ PostSubBufferCHROMIUM(sub_buffer.x(),
+ sub_buffer.y(),
+ sub_buffer.width(),
+ sub_buffer.height());
+ gpu_control_->Echo(base::Bind(&GLES2Implementation::OnSwapBuffersComplete,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+void GLES2Implementation::SetSwapBuffersCompleteCallback(
+ const base::Closure& swap_buffers_complete_callback) {
+ swap_buffers_complete_callback_ = swap_buffers_complete_callback;
+}
+
+void GLES2Implementation::OnSwapBuffersComplete() {
+ if (!swap_buffers_complete_callback_.is_null())
+ swap_buffers_complete_callback_.Run();
+}
+
GLboolean GLES2Implementation::EnableFeatureCHROMIUM(
const char* feature) {
GPU_CLIENT_SINGLE_THREAD_CHECK();
mem,
MappedBuffer(
access, shm_id, mem, shm_offset, target, offset, size)));
- GPU_DCHECK(result.second);
+ DCHECK(result.second);
GPU_CLIENT_LOG(" returned " << mem);
return mem;
}
MappedTexture(
access, shm_id, mem, shm_offset,
target, level, xoffset, yoffset, width, height, format, type)));
- GPU_DCHECK(result.second);
+ DCHECK(result.second);
GPU_CLIENT_LOG(" returned " << mem);
return mem;
}
} else {
std::pair<std::set<std::string>::const_iterator, bool> insert_result =
requestable_extensions_set_.insert(str);
- GPU_DCHECK(insert_result.second);
+ DCHECK(insert_result.second);
result = insert_result.first->c_str();
}
}
void GLES2Implementation::GetProgramInfoCHROMIUMHelper(
GLuint program, std::vector<int8>* result) {
- GPU_DCHECK(result);
+ DCHECK(result);
// Clear the bucket so if the command fails nothing will be in it.
helper_->SetBucketSize(kResultBucketId, 0);
helper_->GetProgramInfoCHROMIUM(program, kResultBucketId);
}
// Make sure they've set size to 0 else the value will be undefined on
// lost context.
- GPU_DCHECK(*size == 0);
+ DCHECK(*size == 0);
std::vector<int8> result;
GetProgramInfoCHROMIUMHelper(program, &result);
if (result.empty()) {
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(
<< ", " << 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;
return;
}
- current_query_ = query;
+ current_queries_[target] = query;
query->Begin(this);
CheckGLError();
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();
}
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();
}
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?");
if (!query->CheckResultsAvailable(helper_)) {
// TODO(gman): Speed this up.
WaitForCmd();
- GPU_CHECK(query->CheckResultsAvailable(helper_));
+ CHECK(query->CheckResultsAvailable(helper_));
}
}
*params = query->GetResult();
<< 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::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();
}
void GLES2Implementation::PushGroupMarkerEXT(