Skip to content

Commit

Permalink
gpu: Add CopyTexImage function to GLImage API.
Browse files Browse the repository at this point in the history
This provides a mechanism for GLImage implementations to optimize
blit image to texture.

In the case of GLImageMemory, this allows us to upload directly
to the destination texture instead of first uploading to a temporary
texture copying pixels from this texture to the destination texture.

BUG=374962

Review URL: https://codereview.chromium.org/536353002

Cr-Commit-Position: refs/heads/master@{#293404}
  • Loading branch information
reveman-chromium authored and Commit bot committed Sep 5, 2014
1 parent f459aa1 commit ce8fbe8
Show file tree
Hide file tree
Showing 20 changed files with 145 additions and 25 deletions.
5 changes: 5 additions & 0 deletions content/common/gpu/stream_texture_android.cc
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,11 @@ void StreamTexture::ReleaseTexImage(unsigned target) {
NOTREACHED();
}

bool StreamTexture::CopyTexImage(unsigned target) {
NOTREACHED();
return false;
}

bool StreamTexture::ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
int z_order,
gfx::OverlayTransform transform,
Expand Down
1 change: 1 addition & 0 deletions content/common/gpu/stream_texture_android.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class StreamTexture : public gfx::GLImage,
virtual gfx::Size GetSize() OVERRIDE;
virtual bool BindTexImage(unsigned target) OVERRIDE;
virtual void ReleaseTexImage(unsigned target) OVERRIDE;
virtual bool CopyTexImage(unsigned target) OVERRIDE;
virtual void WillUseTexImage() OVERRIDE;
virtual void DidUseTexImage() OVERRIDE {}
virtual void WillModifyTexImage() OVERRIDE {}
Expand Down
12 changes: 11 additions & 1 deletion gpu/command_buffer/service/gles2_cmd_decoder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10128,9 +10128,19 @@ void GLES2DecoderImpl::DoCopyTextureCHROMIUM(
dest_texture_ref, GL_TEXTURE_2D, level, true);
}

DoWillUseTexImageIfNeeded(source_texture, source_texture->target());
ScopedModifyPixels modify(dest_texture_ref);

// Try using GLImage::CopyTexImage when possible.
bool unpack_premultiply_alpha_change =
unpack_premultiply_alpha_ ^ unpack_unpremultiply_alpha_;
if (image && !unpack_flip_y_ && !unpack_premultiply_alpha_change && !level) {
glBindTexture(GL_TEXTURE_2D, dest_texture->service_id());
if (image->CopyTexImage(GL_TEXTURE_2D))
return;
}

DoWillUseTexImageIfNeeded(source_texture, source_texture->target());

// GL_TEXTURE_EXTERNAL_OES texture requires apply a transform matrix
// before presenting.
if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2279,6 +2279,7 @@ class MockGLImage : public gfx::GLImage {
MOCK_METHOD1(Destroy, void(bool));
MOCK_METHOD1(BindTexImage, bool(unsigned));
MOCK_METHOD1(ReleaseTexImage, void(unsigned));
MOCK_METHOD1(CopyTexImage, bool(unsigned));
MOCK_METHOD0(WillUseTexImage, void());
MOCK_METHOD0(DidUseTexImage, void());
MOCK_METHOD0(WillModifyTexImage, void());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class GLImageImpl : public gfx::GLImage {
virtual gfx::Size GetSize() OVERRIDE;
virtual bool BindTexImage(unsigned target) OVERRIDE;
virtual void ReleaseTexImage(unsigned target) OVERRIDE;
virtual bool CopyTexImage(unsigned target) OVERRIDE;
virtual void WillUseTexImage() OVERRIDE;
virtual void DidUseTexImage() OVERRIDE {}
virtual void WillModifyTexImage() OVERRIDE {}
Expand Down Expand Up @@ -72,6 +73,11 @@ void GLImageImpl::ReleaseTexImage(unsigned target) {
NOTREACHED();
}

bool GLImageImpl::CopyTexImage(unsigned target) {
NOTREACHED();
return false;
}

void GLImageImpl::WillUseTexImage() {
surface_texture_->UpdateTexImage();
}
Expand Down
6 changes: 6 additions & 0 deletions gpu/command_buffer/service/texture_definition.cc
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class GLImageSync : public gfx::GLImage {
virtual gfx::Size GetSize() OVERRIDE;
virtual bool BindTexImage(unsigned target) OVERRIDE;
virtual void ReleaseTexImage(unsigned target) OVERRIDE;
virtual bool CopyTexImage(unsigned target) OVERRIDE;
virtual void WillUseTexImage() OVERRIDE;
virtual void WillModifyTexImage() OVERRIDE;
virtual void DidModifyTexImage() OVERRIDE;
Expand Down Expand Up @@ -83,6 +84,11 @@ void GLImageSync::ReleaseTexImage(unsigned target) {
NOTREACHED();
}

bool GLImageSync::CopyTexImage(unsigned target) {
NOTREACHED();
return false;
}

void GLImageSync::WillUseTexImage() {
if (buffer_.get())
buffer_->WillRead(this);
Expand Down
2 changes: 2 additions & 0 deletions ui/gl/gl_image.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ GLImage::GLImage() {
GLImage::~GLImage() {
}

bool GLImage::CopyTexImage(unsigned target) { return false; }

void GLImage::SetReleaseAfterUse() {
// Default no-op implementation for workaround.
}
Expand Down
3 changes: 3 additions & 0 deletions ui/gl/gl_image.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ class GL_EXPORT GLImage : public base::RefCounted<GLImage> {
// Release image from texture currently bound to |target|.
virtual void ReleaseTexImage(unsigned target) = 0;

// Copy image to texture currently bound to |target|.
virtual bool CopyTexImage(unsigned target) = 0;

// Called before the texture is used for drawing.
virtual void WillUseTexImage() = 0;

Expand Down
4 changes: 4 additions & 0 deletions ui/gl/gl_image_egl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ bool GLImageEGL::BindTexImage(unsigned target) {
return true;
}

bool GLImageEGL::CopyTexImage(unsigned target) {
return false;
}

bool GLImageEGL::ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
int z_order,
OverlayTransform transform,
Expand Down
1 change: 1 addition & 0 deletions ui/gl/gl_image_egl.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class GL_EXPORT GLImageEGL : public GLImage {
virtual gfx::Size GetSize() OVERRIDE;
virtual bool BindTexImage(unsigned target) OVERRIDE;
virtual void ReleaseTexImage(unsigned target) OVERRIDE {}
virtual bool CopyTexImage(unsigned target) OVERRIDE;
virtual void WillUseTexImage() OVERRIDE {}
virtual void DidUseTexImage() OVERRIDE {}
virtual void WillModifyTexImage() OVERRIDE {}
Expand Down
4 changes: 4 additions & 0 deletions ui/gl/gl_image_glx.cc
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,10 @@ void GLImageGLX::ReleaseTexImage(unsigned target) {
glXReleaseTexImageEXT(gfx::GetXDisplay(), glx_pixmap_, GLX_FRONT_LEFT_EXT);
}

bool GLImageGLX::CopyTexImage(unsigned target) {
return false;
}

bool GLImageGLX::ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
int z_order,
OverlayTransform transform,
Expand Down
1 change: 1 addition & 0 deletions ui/gl/gl_image_glx.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class GL_EXPORT GLImageGLX : public GLImage {
virtual gfx::Size GetSize() OVERRIDE;
virtual bool BindTexImage(unsigned target) OVERRIDE;
virtual void ReleaseTexImage(unsigned target) OVERRIDE;
virtual bool CopyTexImage(unsigned target) OVERRIDE;
virtual void WillUseTexImage() OVERRIDE {}
virtual void DidUseTexImage() OVERRIDE {}
virtual void WillModifyTexImage() OVERRIDE {}
Expand Down
4 changes: 4 additions & 0 deletions ui/gl/gl_image_io_surface.cc
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ bool GLImageIOSurface::BindTexImage(unsigned target) {
return true;
}

bool GLImageIOSurface::CopyTexImage(unsigned target) {
return false;
}

bool GLImageIOSurface::ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
int z_order,
OverlayTransform transform,
Expand Down
1 change: 1 addition & 0 deletions ui/gl/gl_image_io_surface.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class GL_EXPORT GLImageIOSurface : public GLImage {
virtual gfx::Size GetSize() OVERRIDE;
virtual bool BindTexImage(unsigned target) OVERRIDE;
virtual void ReleaseTexImage(unsigned target) OVERRIDE {}
virtual bool CopyTexImage(unsigned target) OVERRIDE;
virtual void WillUseTexImage() OVERRIDE {}
virtual void DidUseTexImage() OVERRIDE {}
virtual void WillModifyTexImage() OVERRIDE {}
Expand Down
101 changes: 79 additions & 22 deletions ui/gl/gl_image_memory.cc
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,10 @@ int BytesPerPixel(unsigned internalformat) {
GLImageMemory::GLImageMemory(const gfx::Size& size, unsigned internalformat)
: memory_(NULL),
size_(size),
internalformat_(internalformat)
internalformat_(internalformat),
in_use_(false),
target_(0),
need_do_bind_tex_image_(false)
#if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \
defined(USE_OZONE)
,
Expand Down Expand Up @@ -122,7 +125,80 @@ gfx::Size GLImageMemory::GetSize() {
}

bool GLImageMemory::BindTexImage(unsigned target) {
TRACE_EVENT0("gpu", "GLImageMemory::BindTexImage");
if (target_ && target_ != target) {
LOG(ERROR) << "GLImage can only be bound to one target";
return false;
}
target_ = target;

// Defer DoBindTexImage if not currently in use.
if (!in_use_) {
need_do_bind_tex_image_ = true;
return true;
}

DoBindTexImage(target);
return true;
}

bool GLImageMemory::CopyTexImage(unsigned target) {
TRACE_EVENT0("gpu", "GLImageMemory::CopyTexImage");

// GL_TEXTURE_EXTERNAL_OES is not a supported CopyTexImage target.
if (target == GL_TEXTURE_EXTERNAL_OES)
return false;

DCHECK(memory_);
glTexImage2D(target,
0, // mip level
TextureFormat(internalformat_),
size_.width(),
size_.height(),
0, // border
DataFormat(internalformat_),
DataType(internalformat_),
memory_);

return true;
}

void GLImageMemory::WillUseTexImage() {
DCHECK(!in_use_);
in_use_ = true;

if (!need_do_bind_tex_image_)
return;

DCHECK(target_);
DoBindTexImage(target_);
}

void GLImageMemory::DidUseTexImage() {
DCHECK(in_use_);
in_use_ = false;
}

bool GLImageMemory::ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
int z_order,
OverlayTransform transform,
const Rect& bounds_rect,
const RectF& crop_rect) {
return false;
}

bool GLImageMemory::HasValidFormat() const {
return ValidFormat(internalformat_);
}

size_t GLImageMemory::Bytes() const {
return size_.GetArea() * BytesPerPixel(internalformat_);
}

void GLImageMemory::DoBindTexImage(unsigned target) {
TRACE_EVENT0("gpu", "GLImageMemory::DoBindTexImage");

DCHECK(need_do_bind_tex_image_);
need_do_bind_tex_image_ = false;

DCHECK(memory_);
#if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \
Expand Down Expand Up @@ -176,8 +252,7 @@ bool GLImageMemory::BindTexImage(unsigned target) {

glEGLImageTargetTexture2DOES(target, egl_image_);
DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());

return true;
return;
}
#endif

Expand All @@ -191,24 +266,6 @@ bool GLImageMemory::BindTexImage(unsigned target) {
DataFormat(internalformat_),
DataType(internalformat_),
memory_);

return true;
}

bool GLImageMemory::HasValidFormat() const {
return ValidFormat(internalformat_);
}

size_t GLImageMemory::Bytes() const {
return size_.GetArea() * BytesPerPixel(internalformat_);
}

bool GLImageMemory::ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
int z_order,
OverlayTransform transform,
const Rect& bounds_rect,
const RectF& crop_rect) {
return false;
}

} // namespace gfx
10 changes: 8 additions & 2 deletions ui/gl/gl_image_memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ class GL_EXPORT GLImageMemory : public GLImage {
virtual gfx::Size GetSize() OVERRIDE;
virtual bool BindTexImage(unsigned target) OVERRIDE;
virtual void ReleaseTexImage(unsigned target) OVERRIDE {}
virtual void WillUseTexImage() OVERRIDE {}
virtual void DidUseTexImage() OVERRIDE {}
virtual bool CopyTexImage(unsigned target) OVERRIDE;
virtual void WillUseTexImage() OVERRIDE;
virtual void DidUseTexImage() OVERRIDE;
virtual void WillModifyTexImage() OVERRIDE {}
virtual void DidModifyTexImage() OVERRIDE {}
virtual bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
Expand All @@ -43,9 +44,14 @@ class GL_EXPORT GLImageMemory : public GLImage {
size_t Bytes() const;

private:
void DoBindTexImage(unsigned target);

const unsigned char* memory_;
const gfx::Size size_;
const unsigned internalformat_;
bool in_use_;
unsigned target_;
bool need_do_bind_tex_image_;
#if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \
defined(USE_OZONE)
unsigned egl_texture_id_;
Expand Down
2 changes: 2 additions & 0 deletions ui/gl/gl_image_stub.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ gfx::Size GLImageStub::GetSize() { return gfx::Size(1, 1); }

bool GLImageStub::BindTexImage(unsigned target) { return true; }

bool GLImageStub::CopyTexImage(unsigned target) { return true; }

bool GLImageStub::ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
int z_order,
OverlayTransform transform,
Expand Down
1 change: 1 addition & 0 deletions ui/gl/gl_image_stub.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class GL_EXPORT GLImageStub : public GLImage {
virtual gfx::Size GetSize() OVERRIDE;
virtual bool BindTexImage(unsigned target) OVERRIDE;
virtual void ReleaseTexImage(unsigned target) OVERRIDE {}
virtual bool CopyTexImage(unsigned target) OVERRIDE;
virtual void WillUseTexImage() OVERRIDE {}
virtual void DidUseTexImage() OVERRIDE {}
virtual void WillModifyTexImage() OVERRIDE {}
Expand Down
4 changes: 4 additions & 0 deletions ui/gl/gl_image_surface_texture.cc
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ bool GLImageSurfaceTexture::BindTexImage(unsigned target) {
return true;
}

bool GLImageSurfaceTexture::CopyTexImage(unsigned target) {
return false;
}

bool GLImageSurfaceTexture::ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
int z_order,
OverlayTransform transform,
Expand Down
1 change: 1 addition & 0 deletions ui/gl/gl_image_surface_texture.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class GL_EXPORT GLImageSurfaceTexture : public GLImage {
virtual gfx::Size GetSize() OVERRIDE;
virtual bool BindTexImage(unsigned target) OVERRIDE;
virtual void ReleaseTexImage(unsigned target) OVERRIDE {}
virtual bool CopyTexImage(unsigned target) OVERRIDE;
virtual void WillUseTexImage() OVERRIDE {}
virtual void DidUseTexImage() OVERRIDE {}
virtual void WillModifyTexImage() OVERRIDE {}
Expand Down

0 comments on commit ce8fbe8

Please sign in to comment.