Skip to content

Commit

Permalink
Plumb through EGL_NV_post_sub_buffer and GLX_MESA_copy_sub_buffer.
Browse files Browse the repository at this point in the history
These two extensions allow a partial swap: just pushing part of the backbuffer to the front buffer. This will allow the WK compositor to push a partial update to the screen instead of a full frame update (https://bugs.webkit.org/show_bug.cgi?id=70533).

We should be able to do something similar for TOUCHUI ImageTransportSurfaces (hence the hooks into GLSurface and the glPostSubBufferCHROMIUM command).

Review URL: http://codereview.chromium.org/8512005

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@109625 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
backer@chromium.org committed Nov 11, 2011
1 parent 9e81482 commit 1c75a37
Show file tree
Hide file tree
Showing 25 changed files with 232 additions and 3 deletions.
14 changes: 14 additions & 0 deletions content/renderer/gpu/webgraphicscontext3d_command_buffer_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,20 @@ void WebGraphicsContext3DCommandBufferImpl::prepareTexture() {
#endif
}

void WebGraphicsContext3DCommandBufferImpl::postSubBufferCHROMIUM(
int x, int y, int width, int height) {
// Same flow control as WebGraphicsContext3DCommandBufferImpl::prepareTexture
// (see above).
RenderViewImpl* renderview =
web_view_ ? RenderViewImpl::FromWebView(web_view_) : NULL;
if (renderview)
renderview->OnViewContextSwapBuffersPosted();
gl_->PostSubBufferCHROMIUM(x, y, width, height);
context_->Echo(base::Bind(
&WebGraphicsContext3DCommandBufferImpl::OnSwapBuffersComplete,
weak_ptr_factory_.GetWeakPtr()));
}

void WebGraphicsContext3DCommandBufferImpl::reshape(int width, int height) {
cached_width_ = width;
cached_height_ = height;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ class WebGraphicsContext3DCommandBufferImpl

virtual WebGLId getPlatformTextureId();
virtual void prepareTexture();
virtual void postSubBufferCHROMIUM(int x, int y, int width, int height);

virtual void activeTexture(WGC3Denum texture);
virtual void attachShader(WebGLId program, WebGLId shader);
Expand Down
13 changes: 13 additions & 0 deletions gpu/GLES2/gl2ext.h
Original file line number Diff line number Diff line change
Expand Up @@ -1349,6 +1349,19 @@ typedef void (GL_APIENTRYP PFNGLENABLEFEATURECHROMIUM) (const GLchar *feature);
#endif
#endif

/* GL_CHROMIUM_post_sub_buffer */
#ifndef GL_CHROMIUM_post_sub_buffer
#define GL_CHROMIUM_post_sub_buffer 1
#ifdef GL_GLEXT_PROTOTYPES
#define glPostSubBufferCHROMIUM GLES2_GET_FUN(PostSubBufferCHROMIUM)
#if !defined(GLES2_USE_CPP_BINDINGS)
GL_APICALL void GL_APIENTRY glPostSubBufferCHROMIUM (GLint x, GLint y, GLint width, GLint height);
#endif
#else
typedef void (GL_APIENTRYP PFNGLPOSTSUBBUFFERCHROMIUM) (GLint x, GLint y, GLint width, GLint height);
#endif
#endif

/* GL_ARB_robustness */
/* This extension is subsetted for the moment, incorporating only the
* enums necessary to describe the reasons that we might encounter for
Expand Down
9 changes: 9 additions & 0 deletions gpu/command_buffer/build_gles2_cmd_buffer.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@
GL_APICALL void GL_APIENTRY glDestroyStreamTextureCHROMIUM (GLuint texture);
GL_APICALL void GL_APIENTRY glPlaceholder453CHROMIUM (void);
GL_APICALL void GL_APIENTRY glGetTranslatedShaderSourceANGLE (GLidShader shader, GLsizeiNotNegative bufsize, GLsizei* length, char* source);
GL_APICALL void GL_APIENTRY glPostSubBufferCHROMIUM (GLint x, GLint y, GLint width, GLint height);
"""

# This is the list of all commmands that will be generated and their Id.
Expand Down Expand Up @@ -433,6 +434,7 @@
'GetMultipleIntegervCHROMIUM': 454,
'GetProgramInfoCHROMIUM': 455,
'GetTranslatedShaderSourceANGLE': 456,
'PostSubBufferCHROMIUM': 457,
}

# This is a list of enum names and their valid values. It is used to map
Expand Down Expand Up @@ -1517,6 +1519,13 @@
'chromium': True,
},
'PixelStorei': {'type': 'Manual'},
'PostSubBufferCHROMIUM': {
'type': 'Custom',
'impl_func': False,
'unit_test': False,
'extension': True,
'chromium': True,
},
'RenderbufferStorage': {
'decoder_func': 'DoRenderbufferStorage',
'gl_test_func': 'glRenderbufferStorageEXT',
Expand Down
3 changes: 3 additions & 0 deletions gpu/command_buffer/client/gles2_c_lib_autogen.h
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,9 @@ void GLES2GetTranslatedShaderSourceANGLE(
gles2::GetGLContext()->GetTranslatedShaderSourceANGLE(
shader, bufsize, length, source);
}
void GLES2PostSubBufferCHROMIUM(GLint x, GLint y, GLint width, GLint height) {
gles2::GetGLContext()->PostSubBufferCHROMIUM(x, y, width, height);
}

#endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_C_LIB_AUTOGEN_H_

6 changes: 6 additions & 0 deletions gpu/command_buffer/client/gles2_cmd_helper_autogen.h
Original file line number Diff line number Diff line change
Expand Up @@ -1247,5 +1247,11 @@
c.Init(shader, bucket_id);
}

void PostSubBufferCHROMIUM(GLint x, GLint y, GLint width, GLint height) {
gles2::PostSubBufferCHROMIUM& c =
GetCmdSpace<gles2::PostSubBufferCHROMIUM>();
c.Init(x, y, width, height);
}

#endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_CMD_HELPER_AUTOGEN_H_

16 changes: 16 additions & 0 deletions gpu/command_buffer/client/gles2_implementation.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2649,5 +2649,21 @@ void GLES2Implementation::DestroyStreamTextureCHROMIUM(GLuint texture) {
helper_->DestroyStreamTextureCHROMIUM(texture);
}

void GLES2Implementation::PostSubBufferCHROMIUM(
GLint x, GLint y, GLint width, GLint height) {
GPU_CLIENT_LOG("[" << this << "] PostSubBufferCHROMIUM("
<< x << ", " << y << ", " << width << ", " << height << ")");
TRACE_EVENT0("gpu", "GLES2::PostSubBufferCHROMIUM");

// Same flow control as GLES2Implementation::SwapBuffers (see comments there).
swap_buffers_tokens_.push(helper_->InsertToken());
helper_->PostSubBufferCHROMIUM(x, y, width, height);
helper_->CommandBufferHelper::Flush();
if (swap_buffers_tokens_.size() > kMaxSwapBuffers + 1) {
helper_->WaitForToken(swap_buffers_tokens_.front());
swap_buffers_tokens_.pop();
}
}

} // namespace gles2
} // namespace gpu
2 changes: 2 additions & 0 deletions gpu/command_buffer/client/gles2_implementation_autogen.h
Original file line number Diff line number Diff line change
Expand Up @@ -1303,5 +1303,7 @@ void GetTranslatedShaderSourceANGLE(
*length = max_size;
}
}
void PostSubBufferCHROMIUM(GLint x, GLint y, GLint width, GLint height);

#endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_IMPLEMENTATION_AUTOGEN_H_

46 changes: 46 additions & 0 deletions gpu/command_buffer/common/gles2_cmd_format_autogen.h
Original file line number Diff line number Diff line change
Expand Up @@ -9165,6 +9165,52 @@ COMPILE_ASSERT(offsetof(GetTranslatedShaderSourceANGLE, shader) == 4,
COMPILE_ASSERT(offsetof(GetTranslatedShaderSourceANGLE, bucket_id) == 8,
OffsetOf_GetTranslatedShaderSourceANGLE_bucket_id_not_8);

struct PostSubBufferCHROMIUM {
typedef PostSubBufferCHROMIUM ValueType;
static const CommandId kCmdId = kPostSubBufferCHROMIUM;
static const cmd::ArgFlags kArgFlags = cmd::kFixed;

static uint32 ComputeSize() {
return static_cast<uint32>(sizeof(ValueType)); // NOLINT
}

void SetHeader() {
header.SetCmd<ValueType>();
}

void Init(GLint _x, GLint _y, GLint _width, GLint _height) {
SetHeader();
x = _x;
y = _y;
width = _width;
height = _height;
}

void* Set(void* cmd, GLint _x, GLint _y, GLint _width, GLint _height) {
static_cast<ValueType*>(cmd)->Init(_x, _y, _width, _height);
return NextCmdAddress<ValueType>(cmd);
}

gpu::CommandHeader header;
int32 x;
int32 y;
int32 width;
int32 height;
};

COMPILE_ASSERT(sizeof(PostSubBufferCHROMIUM) == 20,
Sizeof_PostSubBufferCHROMIUM_is_not_20);
COMPILE_ASSERT(offsetof(PostSubBufferCHROMIUM, header) == 0,
OffsetOf_PostSubBufferCHROMIUM_header_not_0);
COMPILE_ASSERT(offsetof(PostSubBufferCHROMIUM, x) == 4,
OffsetOf_PostSubBufferCHROMIUM_x_not_4);
COMPILE_ASSERT(offsetof(PostSubBufferCHROMIUM, y) == 8,
OffsetOf_PostSubBufferCHROMIUM_y_not_8);
COMPILE_ASSERT(offsetof(PostSubBufferCHROMIUM, width) == 12,
OffsetOf_PostSubBufferCHROMIUM_width_not_12);
COMPILE_ASSERT(offsetof(PostSubBufferCHROMIUM, height) == 16,
OffsetOf_PostSubBufferCHROMIUM_height_not_16);


#endif // GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_FORMAT_AUTOGEN_H_

19 changes: 19 additions & 0 deletions gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
Original file line number Diff line number Diff line change
Expand Up @@ -3559,5 +3559,24 @@ TEST_F(GLES2FormatTest, GetTranslatedShaderSourceANGLE) {
next_cmd, sizeof(cmd));
}

TEST_F(GLES2FormatTest, PostSubBufferCHROMIUM) {
PostSubBufferCHROMIUM& cmd = *GetBufferAs<PostSubBufferCHROMIUM>();
void* next_cmd = cmd.Set(
&cmd,
static_cast<GLint>(11),
static_cast<GLint>(12),
static_cast<GLint>(13),
static_cast<GLint>(14));
EXPECT_EQ(static_cast<uint32>(PostSubBufferCHROMIUM::kCmdId),
cmd.header.command);
EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
EXPECT_EQ(static_cast<GLint>(11), cmd.x);
EXPECT_EQ(static_cast<GLint>(12), cmd.y);
EXPECT_EQ(static_cast<GLint>(13), cmd.width);
EXPECT_EQ(static_cast<GLint>(14), cmd.height);
CheckBytesWrittenMatchesExpectedSize(
next_cmd, sizeof(cmd));
}

#endif // GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_FORMAT_TEST_AUTOGEN_H_

1 change: 1 addition & 0 deletions gpu/command_buffer/common/gles2_cmd_ids_autogen.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@
OP(GetMultipleIntegervCHROMIUM) /* 454 */ \
OP(GetProgramInfoCHROMIUM) /* 455 */ \
OP(GetTranslatedShaderSourceANGLE) /* 456 */ \
OP(PostSubBufferCHROMIUM) /* 457 */ \

enum CommandId {
kStartPoint = cmd::kLastCommonId, // All GLES2 commands start after this.
Expand Down
7 changes: 7 additions & 0 deletions gpu/command_buffer/service/feature_info.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "gpu/command_buffer/service/feature_info.h"
#include "gpu/command_buffer/service/gl_utils.h"
#include "ui/gfx/gl/gl_implementation.h"
#include "ui/gfx/gl/gl_surface.h"

namespace gpu {
namespace gles2 {
Expand Down Expand Up @@ -357,6 +358,12 @@ void FeatureInfo::AddFeatures(const char* desired_features) {
feature_flags_.enable_texture_half_float_linear =
enable_texture_half_float_linear;
feature_flags_.npot_ok = npot_ok;

if (ext.Desire("GL_CHROMIUM_post_sub_buffer") &&
gfx::GLSurface::GetCurrent() &&
gfx::GLSurface::GetCurrent()->SupportsPostSubBuffer()) {
AddExtensionString("GL_CHROMIUM_post_sub_buffer");
}
}

void FeatureInfo::AddExtensionString(const std::string& str) {
Expand Down
14 changes: 14 additions & 0 deletions gpu/command_buffer/service/gles2_cmd_decoder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5740,6 +5740,20 @@ error::Error GLES2DecoderImpl::HandlePixelStorei(
return error::kNoError;
}

error::Error GLES2DecoderImpl::HandlePostSubBufferCHROMIUM(
uint32 immediate_data_size, const gles2::PostSubBufferCHROMIUM& c) {
TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandlePostSubBufferCHROMIUM");
if (!surface_->SupportsPostSubBuffer()) {
SetGLError(GL_INVALID_OPERATION,
"glPostSubBufferCHROMIUM: command not supported by surface");
return error::kNoError;
}
if (surface_->PostSubBuffer(c.x, c.y, c.width, c.height))
return error::kNoError;
else
return error::kLostContext;
}

error::Error GLES2DecoderImpl::GetAttribLocationHelper(
GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
const std::string& name_str) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@
// TODO(gman): DestroyStreamTextureCHROMIUM

// TODO(gman): GetTranslatedShaderSourceANGLE
// TODO(gman): PostSubBufferCHROMIUM
#endif // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_3_AUTOGEN_H_

6 changes: 6 additions & 0 deletions ui/gfx/gl/generate_bindings.py
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,9 @@
'EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target'],
['__eglMustCastToProperFunctionPointerType', ['eglGetProcAddress'],
'const char* procname'],
['EGLBoolean', ['eglPostSubBufferNV'],
'EGLDisplay dpy, EGLSurface surface, '
'EGLint x, EGLint y, EGLint width, EGLint height'],
['EGLBoolean', ['eglQuerySurfacePointerANGLE'],
'EGLDisplay dpy, EGLSurface surface, EGLint attribute, void** value'],
]
Expand Down Expand Up @@ -396,6 +399,9 @@
GLX_FUNCTIONS = [
['XVisualInfo*', ['glXChooseVisual'],
'Display* dpy, int screen, int* attribList'],
['void', ['glXCopySubBufferMESA'],
'Display* dpy, GLXDrawable drawable, '
'int x, int y, int width, int height'],
['GLXContext', ['glXCreateContext'],
'Display* dpy, XVisualInfo* vis, GLXContext shareList, int direct'],
['void', ['glXBindTexImageEXT'],
Expand Down
8 changes: 8 additions & 0 deletions ui/gfx/gl/gl_surface.cc
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,14 @@ unsigned int GLSurface::GetBackingFrameBufferObject() {
return 0;
}

bool GLSurface::SupportsPostSubBuffer() {
return false;
}

bool GLSurface::PostSubBuffer(int x, int y, int width, int height) {
return false;
}

bool GLSurface::OnMakeCurrent(GLContext* context) {
return true;
}
Expand Down
4 changes: 4 additions & 0 deletions ui/gfx/gl/gl_surface.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ class GL_EXPORT GLSurface : public base::RefCounted<GLSurface> {
// FBO. Otherwise returns 0.
virtual unsigned int GetBackingFrameBufferObject();

// Copy part of the backbuffer to the frontbuffer.
virtual bool SupportsPostSubBuffer();
virtual bool PostSubBuffer(int x, int y, int width, int height);

static bool InitializeOneOff();

// Called after a context is made current with this surface. Returns false
Expand Down
34 changes: 32 additions & 2 deletions ui/gfx/gl/gl_surface_egl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,8 @@ EGLNativeDisplayType GLSurfaceEGL::GetNativeDisplay() {
NativeViewGLSurfaceEGL::NativeViewGLSurfaceEGL(bool software,
gfx::PluginWindowHandle window)
: window_(window),
surface_(NULL)
surface_(NULL),
supports_post_sub_buffer_(false)
{
software_ = software;
}
Expand All @@ -190,11 +191,18 @@ bool NativeViewGLSurfaceEGL::Initialize() {
return false;
}

static const EGLint egl_window_attributes_sub_buffer[] = {
EGL_POST_SUB_BUFFER_SUPPORTED_NV, EGL_TRUE,
EGL_NONE
};

// Create a surface for the native window.
surface_ = eglCreateWindowSurface(GetDisplay(),
GetConfig(),
window_,
NULL);
gfx::g_EGL_NV_post_sub_buffer ?
egl_window_attributes_sub_buffer :
NULL);

if (!surface_) {
LOG(ERROR) << "eglCreateWindowSurface failed with error "
Expand All @@ -203,6 +211,13 @@ bool NativeViewGLSurfaceEGL::Initialize() {
return false;
}

EGLint surfaceVal;
EGLBoolean retVal = eglQuerySurface(GetDisplay(),
surface_,
EGL_POST_SUB_BUFFER_SUPPORTED_NV,
&surfaceVal);
supports_post_sub_buffer_ = (surfaceVal && retVal) == EGL_TRUE;

return true;
}

Expand Down Expand Up @@ -247,6 +262,21 @@ EGLSurface NativeViewGLSurfaceEGL::GetHandle() {
return surface_;
}

bool NativeViewGLSurfaceEGL::SupportsPostSubBuffer() {
return supports_post_sub_buffer_;
}

bool NativeViewGLSurfaceEGL::PostSubBuffer(
int x, int y, int width, int height) {
DCHECK(supports_post_sub_buffer_);
if (!eglPostSubBufferNV(GetDisplay(), surface_, x, y, width, height)) {
VLOG(1) << "eglPostSubBufferNV failed with error "
<< GetLastEGLErrorString();
return false;
}
return true;
}

PbufferGLSurfaceEGL::PbufferGLSurfaceEGL(bool software, const gfx::Size& size)
: size_(size),
surface_(NULL) {
Expand Down
Loading

0 comments on commit 1c75a37

Please sign in to comment.