summaryrefslogtreecommitdiffstats
path: root/gpu
diff options
context:
space:
mode:
authorjamesr@chromium.org <jamesr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-13 23:30:22 +0000
committerjamesr@chromium.org <jamesr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-13 23:30:22 +0000
commitc76fe6734b1b5e4985828c634e582063b0267eb9 (patch)
treeb447ac0e87aa8828b8664cbfa8195ae13821c918 /gpu
parentb597d9b28154b9a6a707b483c4fdab7efa8e7c47 (diff)
downloadchromium_src-c76fe6734b1b5e4985828c634e582063b0267eb9.zip
chromium_src-c76fe6734b1b5e4985828c634e582063b0267eb9.tar.gz
chromium_src-c76fe6734b1b5e4985828c634e582063b0267eb9.tar.bz2
Implicitly ensure backbuffer creation on draw
Instead of having a special IPC channel to ensure a backbuffer is allocated for a given GL context, we can create it implicitly on the first draw attempt into FBO 0. If this fails, the context is considered lost. BUG=181120 Review URL: https://codereview.chromium.org/112303002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@240797 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu')
-rwxr-xr-xgpu/command_buffer/build_gles2_cmd_buffer.py17
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc35
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_autogen.h33
3 files changed, 61 insertions, 24 deletions
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py
index 49330b4..0f2e49a 100755
--- a/gpu/command_buffer/build_gles2_cmd_buffer.py
+++ b/gpu/command_buffer/build_gles2_cmd_buffer.py
@@ -2876,17 +2876,18 @@ COMPILE_ASSERT(offsetof(%(cmd_name)s::Result, %(field_name)s) == %(offset)d,
def WriteHandlerDeferReadWrite(self, func, file):
"""Writes the code to handle deferring reads or writes."""
- defer_reads = func.GetInfo('defer_reads')
defer_draws = func.GetInfo('defer_draws')
- conditions = []
+ defer_reads = func.GetInfo('defer_reads')
+ if defer_draws or defer_reads:
+ file.Write(" error::Error error;\n")
if defer_draws:
- conditions.append('ShouldDeferDraws()');
+ file.Write(" error = WillAccessBoundFramebufferForDraw();\n")
+ file.Write(" if (error != error::kNoError)\n")
+ file.Write(" return error;\n")
if defer_reads:
- conditions.append('ShouldDeferReads()');
- if not conditions:
- return
- file.Write(" if (%s)\n" % ' || '.join(conditions))
- file.Write(" return error::kDeferCommandUntilLater;\n")
+ file.Write(" error = WillAccessBoundFramebufferForRead();\n")
+ file.Write(" if (error != error::kNoError)\n")
+ file.Write(" return error;\n")
def WriteValidUnitTest(self, func, file, test, extra = {}):
"""Writes a valid unit test."""
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index a68cd66..724d537 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -1539,6 +1539,26 @@ class GLES2DecoderImpl : public GLES2Decoder,
surface_->DeferDraws();
}
+ error::Error WillAccessBoundFramebufferForDraw() {
+ if (ShouldDeferDraws())
+ return error::kDeferCommandUntilLater;
+ if (!offscreen_target_frame_buffer_.get() &&
+ !framebuffer_state_.bound_draw_framebuffer.get() &&
+ !surface_->SetBackbufferAllocation(true))
+ return error::kLostContext;
+ return error::kNoError;
+ }
+
+ error::Error WillAccessBoundFramebufferForRead() {
+ if (ShouldDeferReads())
+ return error::kDeferCommandUntilLater;
+ if (!offscreen_target_frame_buffer_.get() &&
+ !framebuffer_state_.bound_read_framebuffer.get() &&
+ !surface_->SetBackbufferAllocation(true))
+ return error::kLostContext;
+ return error::kNoError;
+ }
+
void ProcessPendingReadPixels();
void FinishReadPixels(const cmds::ReadPixels& c, GLuint buffer);
@@ -6342,8 +6362,9 @@ error::Error GLES2DecoderImpl::DoDrawArrays(
GLint first,
GLsizei count,
GLsizei primcount) {
- if (ShouldDeferDraws())
- return error::kDeferCommandUntilLater;
+ error::Error error = WillAccessBoundFramebufferForDraw();
+ if (error != error::kNoError)
+ return error;
if (!validators_->draw_mode.IsValid(mode)) {
LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
return error::kNoError;
@@ -6442,8 +6463,9 @@ error::Error GLES2DecoderImpl::DoDrawElements(
GLenum type,
int32 offset,
GLsizei primcount) {
- if (ShouldDeferDraws())
- return error::kDeferCommandUntilLater;
+ error::Error error = WillAccessBoundFramebufferForDraw();
+ if (error != error::kNoError)
+ return error;
if (!state_.vertex_attrib_manager->element_array_buffer()) {
LOCAL_SET_GL_ERROR(
GL_INVALID_OPERATION, function_name, "No element array buffer bound");
@@ -7223,8 +7245,9 @@ void GLES2DecoderImpl::FinishReadPixels(
error::Error GLES2DecoderImpl::HandleReadPixels(
uint32 immediate_data_size, const cmds::ReadPixels& c) {
- if (ShouldDeferReads())
- return error::kDeferCommandUntilLater;
+ error::Error fbo_error = WillAccessBoundFramebufferForRead();
+ if (fbo_error != error::kNoError)
+ return fbo_error;
GLint x = c.x;
GLint y = c.y;
GLsizei width = c.width;
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
index a349583..ddc00fc 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
@@ -236,8 +236,10 @@ error::Error GLES2DecoderImpl::HandleCheckFramebufferStatus(
error::Error GLES2DecoderImpl::HandleClear(
uint32 immediate_data_size, const gles2::cmds::Clear& c) {
- if (ShouldDeferDraws())
- return error::kDeferCommandUntilLater;
+ error::Error error;
+ error = WillAccessBoundFramebufferForDraw();
+ if (error != error::kNoError)
+ return error;
GLbitfield mask = static_cast<GLbitfield>(c.mask);
DoClear(mask);
return error::kNoError;
@@ -357,8 +359,10 @@ error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2D(
error::Error GLES2DecoderImpl::HandleCopyTexImage2D(
uint32 immediate_data_size, const gles2::cmds::CopyTexImage2D& c) {
- if (ShouldDeferReads())
- return error::kDeferCommandUntilLater;
+ error::Error error;
+ error = WillAccessBoundFramebufferForRead();
+ if (error != error::kNoError)
+ return error;
GLenum target = static_cast<GLenum>(c.target);
GLint level = static_cast<GLint>(c.level);
GLenum internalformat = static_cast<GLenum>(c.internalformat);
@@ -395,8 +399,10 @@ error::Error GLES2DecoderImpl::HandleCopyTexImage2D(
error::Error GLES2DecoderImpl::HandleCopyTexSubImage2D(
uint32 immediate_data_size, const gles2::cmds::CopyTexSubImage2D& c) {
- if (ShouldDeferReads())
- return error::kDeferCommandUntilLater;
+ error::Error error;
+ error = WillAccessBoundFramebufferForRead();
+ if (error != error::kNoError)
+ return error;
GLenum target = static_cast<GLenum>(c.target);
GLint level = static_cast<GLint>(c.level);
GLint xoffset = static_cast<GLint>(c.xoffset);
@@ -669,8 +675,10 @@ error::Error GLES2DecoderImpl::HandleEnableVertexAttribArray(
error::Error GLES2DecoderImpl::HandleFinish(
uint32 immediate_data_size, const gles2::cmds::Finish& c) {
- if (ShouldDeferReads())
- return error::kDeferCommandUntilLater;
+ error::Error error;
+ error = WillAccessBoundFramebufferForRead();
+ if (error != error::kNoError)
+ return error;
DoFinish();
return error::kNoError;
}
@@ -2631,8 +2639,13 @@ error::Error GLES2DecoderImpl::HandleViewport(
error::Error GLES2DecoderImpl::HandleBlitFramebufferCHROMIUM(
uint32 immediate_data_size,
const gles2::cmds::BlitFramebufferCHROMIUM& c) {
- if (ShouldDeferDraws() || ShouldDeferReads())
- return error::kDeferCommandUntilLater;
+ error::Error error;
+ error = WillAccessBoundFramebufferForDraw();
+ if (error != error::kNoError)
+ return error;
+ error = WillAccessBoundFramebufferForRead();
+ if (error != error::kNoError)
+ return error;
GLint srcX0 = static_cast<GLint>(c.srcX0);
GLint srcY0 = static_cast<GLint>(c.srcY0);
GLint srcX1 = static_cast<GLint>(c.srcX1);