summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorreveman <reveman@chromium.org>2015-10-19 16:38:48 -0700
committerCommit bot <commit-bot@chromium.org>2015-10-19 23:39:22 +0000
commit44429f23f3899d52c9493c114ae9b62e1ddeb7af (patch)
treee74bae28607a9c238eaf3e3ec2c4f1466f7d61e3
parentca96543ef138fe76457b5103bb02eebfde401387 (diff)
downloadchromium_src-44429f23f3899d52c9493c114ae9b62e1ddeb7af.zip
chromium_src-44429f23f3899d52c9493c114ae9b62e1ddeb7af.tar.gz
chromium_src-44429f23f3899d52c9493c114ae9b62e1ddeb7af.tar.bz2
Revert of ui: Move GLImage::BindTexImage fallback from GLImage implementations to GLES2CmdDecoder. (patchset #15 id:280001 of https://codereview.chromium.org/1401423003/ )
Reason for revert: Causing android gpu bots to fail Original issue's description: > ui: Move GLImage::BindTexImage fallback from GLImage implementations to GLES2CmdDecoder. > > This allows the GPU service to properly track the memory usage > image backed textures. > > It also reduces the complexity of GLImage implementations > significantly and makes it easier to support format and > buffer types that require a copy or conversion of data to > be used for sampling. > > This change also includes a few minor GLImage cleanups such > as removing gfx:: namespace prefix in places where it's not > needed and making the CopyTexImage GLImage test not part of > the core GLImage tests as it's optional to support that > function. > > BUG=526298 > TEST=gl_tests --gtest_filter=GpuMemoryBuffer*, gpu_unittests, gl_unittests --gtest_filter=GLImage* > > Committed: https://crrev.com/ac2696e324bda3824952148f831e76a8b80594b3 > Cr-Commit-Position: refs/heads/master@{#354870} TBR=dcastagna@chromium.org,ericrk@chromium.org,fsamuel@chromium.org,liberato@chromium.org,sievers@chromium.org NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG=526298 Review URL: https://codereview.chromium.org/1418483003 Cr-Commit-Position: refs/heads/master@{#354914}
-rw-r--r--components/mus/gles2/command_buffer_local.cc11
-rw-r--r--content/common/gpu/media/android_deferred_rendering_backing_strategy.cc2
-rw-r--r--content/common/gpu/media/avda_codec_image.cc50
-rw-r--r--content/common/gpu/media/avda_codec_image.h5
-rw-r--r--content/common/gpu/media/gpu_video_decode_accelerator.cc6
-rw-r--r--content/common/gpu/stream_texture_android.cc26
-rw-r--r--content/common/gpu/stream_texture_android.h6
-rw-r--r--gpu/command_buffer/service/framebuffer_manager.cc47
-rw-r--r--gpu/command_buffer/service/framebuffer_manager.h37
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc276
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc99
-rw-r--r--gpu/command_buffer/service/mailbox_manager_sync.cc8
-rw-r--r--gpu/command_buffer/service/stream_texture_manager_in_process_android.cc46
-rw-r--r--gpu/command_buffer/service/texture_definition.cc37
-rw-r--r--gpu/command_buffer/service/texture_manager.cc63
-rw-r--r--gpu/command_buffer/service/texture_manager.h48
-rw-r--r--gpu/command_buffer/service/texture_manager_unittest.cc18
-rw-r--r--ui/gl/BUILD.gn1
-rw-r--r--ui/gl/gl_image.h32
-rw-r--r--ui/gl/gl_image_egl.cc15
-rw-r--r--ui/gl/gl_image_egl.h13
-rw-r--r--ui/gl/gl_image_glx.cc52
-rw-r--r--ui/gl/gl_image_glx.h13
-rw-r--r--ui/gl/gl_image_io_surface.h23
-rw-r--r--ui/gl/gl_image_io_surface.mm28
-rw-r--r--ui/gl/gl_image_memory.cc224
-rw-r--r--ui/gl/gl_image_memory.h29
-rw-r--r--ui/gl/gl_image_ozone_native_pixmap.cc23
-rw-r--r--ui/gl/gl_image_ozone_native_pixmap.h2
-rw-r--r--ui/gl/gl_image_ref_counted_memory.cc15
-rw-r--r--ui/gl/gl_image_ref_counted_memory.h4
-rw-r--r--ui/gl/gl_image_ref_counted_memory_unittest.cc4
-rw-r--r--ui/gl/gl_image_shared_memory.cc29
-rw-r--r--ui/gl/gl_image_shared_memory.h9
-rw-r--r--ui/gl/gl_image_shared_memory_unittest.cc4
-rw-r--r--ui/gl/gl_image_stub.cc10
-rw-r--r--ui/gl/gl_image_stub.h9
-rw-r--r--ui/gl/gl_image_surface_texture.cc15
-rw-r--r--ui/gl/gl_image_surface_texture.h13
-rw-r--r--ui/gl/gl_tests.gyp1
-rw-r--r--ui/gl/test/gl_image_test_template.h62
41 files changed, 867 insertions, 548 deletions
diff --git a/components/mus/gles2/command_buffer_local.cc b/components/mus/gles2/command_buffer_local.cc
index 138f707..ede0274 100644
--- a/components/mus/gles2/command_buffer_local.cc
+++ b/components/mus/gles2/command_buffer_local.cc
@@ -5,7 +5,6 @@
#include "components/mus/gles2/command_buffer_local.h"
#include "base/bind.h"
-#include "base/memory/shared_memory.h"
#include "components/mus/gles2/command_buffer_local_client.h"
#include "components/mus/gles2/gpu_memory_tracker.h"
#include "components/mus/gles2/mojo_gpu_memory_buffer.h"
@@ -20,7 +19,7 @@
#include "gpu/command_buffer/service/valuebuffer_manager.h"
#include "ui/gfx/vsync_provider.h"
#include "ui/gl/gl_context.h"
-#include "ui/gl/gl_image_shared_memory.h"
+#include "ui/gl/gl_image_memory.h"
#include "ui/gl/gl_surface.h"
namespace mus {
@@ -136,12 +135,12 @@ int32_t CommandBufferLocal::CreateImage(ClientBuffer buffer,
MojoGpuMemoryBufferImpl* gpu_memory_buffer =
MojoGpuMemoryBufferImpl::FromClientBuffer(buffer);
- gfx::GpuMemoryBufferHandle handle = gpu_memory_buffer->GetHandle();
- scoped_refptr<gfx::GLImageSharedMemory> image(new gfx::GLImageSharedMemory(
+ scoped_refptr<gfx::GLImageMemory> image(new gfx::GLImageMemory(
gfx::Size(static_cast<int>(width), static_cast<int>(height)),
internalformat));
- if (!image->Initialize(base::SharedMemory::DuplicateHandle(handle.handle),
- handle.id, gpu_memory_buffer->GetFormat())) {
+ if (!image->Initialize(
+ static_cast<const unsigned char*>(gpu_memory_buffer->GetMemory()),
+ gpu_memory_buffer->GetFormat())) {
return -1;
}
diff --git a/content/common/gpu/media/android_deferred_rendering_backing_strategy.cc b/content/common/gpu/media/android_deferred_rendering_backing_strategy.cc
index db83791..cdfc7af 100644
--- a/content/common/gpu/media/android_deferred_rendering_backing_strategy.cc
+++ b/content/common/gpu/media/android_deferred_rendering_backing_strategy.cc
@@ -110,7 +110,7 @@ void AndroidDeferredRenderingBackingStrategy::SetImageForPicture(
}
texture_manager->SetLevelImage(texture_ref, GetTextureTarget(), 0,
- image.get(), gpu::gles2::Texture::UNBOUND);
+ image.get());
}
void AndroidDeferredRenderingBackingStrategy::UseCodecBufferForPictureBuffer(
diff --git a/content/common/gpu/media/avda_codec_image.cc b/content/common/gpu/media/avda_codec_image.cc
index b6242a9..062b39b 100644
--- a/content/common/gpu/media/avda_codec_image.cc
+++ b/content/common/gpu/media/avda_codec_image.cc
@@ -5,7 +5,6 @@
#include "content/common/gpu/media/avda_codec_image.h"
#include "content/common/gpu/media/avda_shared_state.h"
-#include "gpu/command_buffer/service/context_group.h"
#include "gpu/command_buffer/service/context_state.h"
#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
#include "gpu/command_buffer/service/texture_manager.h"
@@ -51,12 +50,18 @@ unsigned AVDACodecImage::GetInternalFormat() {
}
bool AVDACodecImage::BindTexImage(unsigned target) {
- return false;
+ return true;
}
void AVDACodecImage::ReleaseTexImage(unsigned target) {}
-bool AVDACodecImage::CopyTexImage(unsigned target) {
+bool AVDACodecImage::CopyTexSubImage(unsigned target,
+ const gfx::Point& offset,
+ const gfx::Rect& rect) {
+ return false;
+}
+
+void AVDACodecImage::WillUseTexImage() {
// Have we bound the SurfaceTexture's texture handle to the active
// texture unit yet?
bool bound_texture = false;
@@ -70,38 +75,29 @@ bool AVDACodecImage::CopyTexImage(unsigned target) {
// Make sure that we have the right image in the front buffer.
bound_texture |= UpdateSurfaceTexture();
+ // TODO(liberato): Handle the texture matrix properly.
+ // Either we can update the shader with it or we can move all of the logic
+ // to updateTexImage() to the right place in the cc to send it to the shader.
+ // For now, we just skip it. crbug.com/530681
+
// Sneakily bind the ST texture handle in the real GL context.
// If we called UpdateTexImage() to update the ST front buffer, then we can
// skip this. Since one draw/frame is the common case, we optimize for it.
if (!bound_texture)
glBindTexture(GL_TEXTURE_EXTERNAL_OES,
shared_state_->surface_texture_service_id());
-
- // TODO(liberato): Handle the texture matrix properly.
- // Either we can update the shader with it or we can move all of the logic
- // to updateTexImage() to the right place in the cc to send it to the shader.
- // For now, we just skip it. crbug.com/530681
-
- gpu::gles2::TextureManager* texture_manager =
- decoder_->GetContextGroup()->texture_manager();
- gpu::gles2::Texture* texture =
- texture_manager->GetTextureForServiceId(
- shared_state_->surface_texture_service_id());
- if (texture) {
- // By setting image state to UNBOUND instead of COPIED we ensure that
- // CopyTexImage() is called each time the surface texture is used for
- // drawing.
- texture->SetLevelImage(GL_TEXTURE_EXTERNAL_OES, 0, this,
- gpu::gles2::Texture::UNBOUND);
- }
-
- return true;
}
-bool AVDACodecImage::CopyTexSubImage(unsigned target,
- const gfx::Point& offset,
- const gfx::Rect& rect) {
- return false;
+void AVDACodecImage::DidUseTexImage() {
+ // Unbind the ST's service_id in the real GL context in favor of whatever
+ // the decoder thinks is bound there.
+ const gpu::gles2::ContextState* state = decoder_->GetContextState();
+ const gpu::gles2::TextureUnit& active_unit =
+ state->texture_units[state->active_texture_unit];
+ glBindTexture(GL_TEXTURE_EXTERNAL_OES,
+ active_unit.bound_texture_external_oes.get()
+ ? active_unit.bound_texture_external_oes->service_id()
+ : 0);
}
bool AVDACodecImage::ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
diff --git a/content/common/gpu/media/avda_codec_image.h b/content/common/gpu/media/avda_codec_image.h
index 0ced55c..7550dee 100644
--- a/content/common/gpu/media/avda_codec_image.h
+++ b/content/common/gpu/media/avda_codec_image.h
@@ -29,10 +29,13 @@ class AVDACodecImage : public gfx::GLImage {
unsigned GetInternalFormat() override;
bool BindTexImage(unsigned target) override;
void ReleaseTexImage(unsigned target) override;
- bool CopyTexImage(unsigned target) override;
bool CopyTexSubImage(unsigned target,
const gfx::Point& offset,
const gfx::Rect& rect) override;
+ void WillUseTexImage() override;
+ void DidUseTexImage() override;
+ void WillModifyTexImage() override {}
+ void DidModifyTexImage() override {}
bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
int z_order,
gfx::OverlayTransform transform,
diff --git a/content/common/gpu/media/gpu_video_decode_accelerator.cc b/content/common/gpu/media/gpu_video_decode_accelerator.cc
index 3a0071f..0de11be 100644
--- a/content/common/gpu/media/gpu_video_decode_accelerator.cc
+++ b/content/common/gpu/media/gpu_video_decode_accelerator.cc
@@ -341,10 +341,8 @@ void GpuVideoDecodeAccelerator::BindImage(uint32 client_texture_id,
gpu::gles2::TextureManager* texture_manager =
command_decoder->GetContextGroup()->texture_manager();
gpu::gles2::TextureRef* ref = texture_manager->GetTexture(client_texture_id);
- if (ref) {
- texture_manager->SetLevelImage(ref, texture_target, 0, image.get(),
- gpu::gles2::Texture::BOUND);
- }
+ if (ref)
+ texture_manager->SetLevelImage(ref, texture_target, 0, image.get());
}
scoped_ptr<media::VideoDecodeAccelerator>
diff --git a/content/common/gpu/stream_texture_android.cc b/content/common/gpu/stream_texture_android.cc
index 3dabc09..20f1da7 100644
--- a/content/common/gpu/stream_texture_android.cc
+++ b/content/common/gpu/stream_texture_android.cc
@@ -45,9 +45,8 @@ bool StreamTexture::Create(
texture_manager->SetLevelInfo(texture, GL_TEXTURE_EXTERNAL_OES, 0, GL_RGBA,
size.width(), size.height(), 1, 0, GL_RGBA,
GL_UNSIGNED_BYTE, gfx::Rect(size));
- texture_manager->SetLevelImage(texture, GL_TEXTURE_EXTERNAL_OES, 0,
- gl_image.get(),
- gpu::gles2::Texture::UNBOUND);
+ texture_manager->SetLevelImage(
+ texture, GL_TEXTURE_EXTERNAL_OES, 0, gl_image.get());
return true;
}
@@ -64,7 +63,6 @@ StreamTexture::StreamTexture(GpuCommandBufferStub* owner_stub,
owner_stub_(owner_stub),
route_id_(route_id),
has_listener_(false),
- texture_id_(texture_id),
weak_factory_(this) {
owner_stub->AddDestructionObserver(this);
memset(current_matrix_, 0, sizeof(current_matrix_));
@@ -94,11 +92,9 @@ void StreamTexture::Destroy(bool have_context) {
NOTREACHED();
}
-bool StreamTexture::CopyTexImage(unsigned target) {
- DCHECK_EQ(target, static_cast<unsigned>(GL_TEXTURE_EXTERNAL_OES));
-
+void StreamTexture::WillUseTexImage() {
if (!owner_stub_ || !surface_texture_.get())
- return true;
+ return;
if (has_pending_frame_) {
scoped_ptr<ui::ScopedMakeCurrent> scoped_make_current;
@@ -132,18 +128,6 @@ bool StreamTexture::CopyTexImage(unsigned target) {
? active_unit.bound_texture_external_oes->service_id()
: 0);
}
-
- TextureManager* texture_manager =
- owner_stub_->decoder()->GetContextGroup()->texture_manager();
- gpu::gles2::Texture* texture =
- texture_manager->GetTextureForServiceId(texture_id_);
- if (texture) {
- // By setting image state to UNBOUND instead of COPIED we ensure that
- // CopyTexImage() is called each time the surface texture is used for
- // drawing.
- texture->SetLevelImage(GL_TEXTURE_EXTERNAL_OES, 0, this,
- gpu::gles2::Texture::UNBOUND);
- }
}
if (has_listener_ && has_valid_frame_) {
@@ -160,8 +144,6 @@ bool StreamTexture::CopyTexImage(unsigned target) {
new GpuStreamTextureMsg_MatrixChanged(route_id_, params));
}
}
-
- return true;
}
void StreamTexture::OnFrameAvailable() {
diff --git a/content/common/gpu/stream_texture_android.h b/content/common/gpu/stream_texture_android.h
index 94a0848..cce4502c 100644
--- a/content/common/gpu/stream_texture_android.h
+++ b/content/common/gpu/stream_texture_android.h
@@ -38,10 +38,13 @@ class StreamTexture : public gfx::GLImage,
unsigned GetInternalFormat() override;
bool BindTexImage(unsigned target) override;
void ReleaseTexImage(unsigned target) override;
- bool CopyTexImage(unsigned target) override;
bool CopyTexSubImage(unsigned target,
const gfx::Point& offset,
const gfx::Rect& rect) override;
+ void WillUseTexImage() override;
+ void DidUseTexImage() override {}
+ void WillModifyTexImage() override {}
+ void DidModifyTexImage() override {}
bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
int z_order,
gfx::OverlayTransform transform,
@@ -82,7 +85,6 @@ class StreamTexture : public gfx::GLImage,
GpuCommandBufferStub* owner_stub_;
int32 route_id_;
bool has_listener_;
- uint32 texture_id_;
base::WeakPtrFactory<StreamTexture> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(StreamTexture);
diff --git a/gpu/command_buffer/service/framebuffer_manager.cc b/gpu/command_buffer/service/framebuffer_manager.cc
index 2460a1e..b78a5dc 100644
--- a/gpu/command_buffer/service/framebuffer_manager.cc
+++ b/gpu/command_buffer/service/framebuffer_manager.cc
@@ -87,6 +87,8 @@ class RenderbufferAttachment
renderbuffer_->AddToSignature(signature);
}
+ void OnWillRenderTo() const override {}
+ void OnDidRenderTo() const override {}
bool FormsFeedbackLoop(TextureRef* /* texture */,
GLint /*level */) const override {
return false;
@@ -177,6 +179,7 @@ class TextureAttachment
void DetachFromFramebuffer(Framebuffer* framebuffer) const override {
texture_ref_->texture()->DetachFromFramebuffer();
+ framebuffer->OnTextureRefDetached(texture_ref_.get());
}
bool ValidForAttachmentType(GLenum attachment_type,
@@ -211,6 +214,14 @@ class TextureAttachment
texture_ref_.get(), target_, level_, signature);
}
+ void OnWillRenderTo() const override {
+ texture_ref_->texture()->OnWillModifyPixels();
+ }
+
+ void OnDidRenderTo() const override {
+ texture_ref_->texture()->OnDidModifyPixels();
+ }
+
bool FormsFeedbackLoop(TextureRef* texture, GLint level) const override {
return texture == texture_ref_.get() && level == level_;
}
@@ -227,6 +238,10 @@ class TextureAttachment
DISALLOW_COPY_AND_ASSIGN(TextureAttachment);
};
+FramebufferManager::TextureDetachObserver::TextureDetachObserver() {}
+
+FramebufferManager::TextureDetachObserver::~TextureDetachObserver() {}
+
FramebufferManager::FramebufferManager(
uint32 max_draw_buffers,
uint32 max_color_attachments,
@@ -698,6 +713,28 @@ const Framebuffer::Attachment* Framebuffer::GetReadBufferAttachment() const {
return GetAttachment(read_buffer_);
}
+void Framebuffer::OnTextureRefDetached(TextureRef* texture) {
+ manager_->OnTextureRefDetached(texture);
+}
+
+void Framebuffer::OnWillRenderTo(GLenum attachment) const {
+ for (AttachmentMap::const_iterator it = attachments_.begin();
+ it != attachments_.end(); ++it) {
+ if (attachment == 0 || attachment == it->first) {
+ it->second->OnWillRenderTo();
+ }
+ }
+}
+
+void Framebuffer::OnDidRenderTo(GLenum attachment) const {
+ for (AttachmentMap::const_iterator it = attachments_.begin();
+ it != attachments_.end(); ++it) {
+ if (attachment == 0 || attachment == it->first) {
+ it->second->OnDidRenderTo();
+ }
+ }
+}
+
bool FramebufferManager::GetClientId(
GLuint service_id, GLuint* client_id) const {
// This doesn't need to be fast. It's only used during slow queries.
@@ -735,5 +772,15 @@ bool FramebufferManager::IsComplete(
framebuffer_state_change_count_;
}
+void FramebufferManager::OnTextureRefDetached(TextureRef* texture) {
+ for (TextureDetachObserverVector::iterator it =
+ texture_detach_observers_.begin();
+ it != texture_detach_observers_.end();
+ ++it) {
+ TextureDetachObserver* observer = *it;
+ observer->OnTextureRefDetachedFromFramebuffer(texture);
+ }
+}
+
} // namespace gles2
} // namespace gpu
diff --git a/gpu/command_buffer/service/framebuffer_manager.h b/gpu/command_buffer/service/framebuffer_manager.h
index db78ffe..7216654 100644
--- a/gpu/command_buffer/service/framebuffer_manager.h
+++ b/gpu/command_buffer/service/framebuffer_manager.h
@@ -52,6 +52,8 @@ class GPU_EXPORT Framebuffer : public base::RefCounted<Framebuffer> {
virtual size_t GetSignatureSize(TextureManager* texture_manager) const = 0;
virtual void AddToSignature(
TextureManager* texture_manager, std::string* signature) const = 0;
+ virtual void OnWillRenderTo() const = 0;
+ virtual void OnDidRenderTo() const = 0;
virtual bool FormsFeedbackLoop(TextureRef* texture, GLint level) const = 0;
protected:
@@ -158,6 +160,13 @@ class GPU_EXPORT Framebuffer : public base::RefCounted<Framebuffer> {
// formats.
bool HasSameInternalFormatsMRT() const;
+ void OnTextureRefDetached(TextureRef* texture);
+
+ // If attachment is 0, apply to all attachments; otherwise, apply only to
+ // the specified attachment.
+ void OnWillRenderTo(GLenum attachment) const;
+ void OnDidRenderTo(GLenum attachment) const;
+
void set_read_buffer(GLenum read_buffer) {
read_buffer_ = read_buffer;
}
@@ -233,6 +242,17 @@ struct DecoderFramebufferState {
// so we can correctly clear them.
class GPU_EXPORT FramebufferManager {
public:
+ class GPU_EXPORT TextureDetachObserver {
+ public:
+ TextureDetachObserver();
+ virtual ~TextureDetachObserver();
+
+ virtual void OnTextureRefDetachedFromFramebuffer(TextureRef* texture) = 0;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TextureDetachObserver);
+ };
+
FramebufferManager(uint32 max_draw_buffers,
uint32 max_color_attachments,
ContextType context_type,
@@ -270,6 +290,18 @@ class GPU_EXPORT FramebufferManager {
(framebuffer_state_change_count_ + 1) | 0x80000000U;
}
+ void AddObserver(TextureDetachObserver* observer) {
+ texture_detach_observers_.push_back(observer);
+ }
+
+ void RemoveObserver(TextureDetachObserver* observer) {
+ texture_detach_observers_.erase(
+ std::remove(texture_detach_observers_.begin(),
+ texture_detach_observers_.end(),
+ observer),
+ texture_detach_observers_.end());
+ }
+
ContextType context_type() const { return context_type_; }
private:
@@ -278,6 +310,8 @@ class GPU_EXPORT FramebufferManager {
void StartTracking(Framebuffer* framebuffer);
void StopTracking(Framebuffer* framebuffer);
+ void OnTextureRefDetached(TextureRef* texture);
+
FramebufferCompletenessCache* GetFramebufferComboCompleteCache() {
return framebuffer_combo_complete_cache_.get();
}
@@ -302,6 +336,9 @@ class GPU_EXPORT FramebufferManager {
ContextType context_type_;
+ typedef std::vector<TextureDetachObserver*> TextureDetachObserverVector;
+ TextureDetachObserverVector texture_detach_observers_;
+
scoped_refptr<FramebufferCompletenessCache> framebuffer_combo_complete_cache_;
DISALLOW_COPY_AND_ASSIGN(FramebufferManager);
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 3b45922..c8ffe3a 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -639,6 +639,49 @@ class ScopedResolvedFrameBufferBinder {
DISALLOW_COPY_AND_ASSIGN(ScopedResolvedFrameBufferBinder);
};
+class ScopedModifyPixels {
+ public:
+ explicit ScopedModifyPixels(TextureRef* ref);
+ ~ScopedModifyPixels();
+
+ private:
+ TextureRef* ref_;
+};
+
+ScopedModifyPixels::ScopedModifyPixels(TextureRef* ref) : ref_(ref) {
+ if (ref_)
+ ref_->texture()->OnWillModifyPixels();
+}
+
+ScopedModifyPixels::~ScopedModifyPixels() {
+ if (ref_)
+ ref_->texture()->OnDidModifyPixels();
+}
+
+class ScopedRenderTo {
+ public:
+ explicit ScopedRenderTo(Framebuffer* framebuffer)
+ : ScopedRenderTo(framebuffer, 0) {}
+ ScopedRenderTo(Framebuffer* framebuffer, GLenum attachment);
+ ~ScopedRenderTo();
+
+ private:
+ const Framebuffer* framebuffer_;
+ GLenum attachment_;
+};
+
+ScopedRenderTo::ScopedRenderTo(Framebuffer* framebuffer, GLenum attachment)
+ : framebuffer_(framebuffer),
+ attachment_(attachment) {
+ if (framebuffer_)
+ framebuffer_->OnWillRenderTo(attachment_);
+}
+
+ScopedRenderTo::~ScopedRenderTo() {
+ if (framebuffer_)
+ framebuffer_->OnDidRenderTo(attachment_);
+}
+
// Encapsulates an OpenGL texture.
class BackTexture {
public:
@@ -791,7 +834,9 @@ void GLES2Decoder::EndDecoding() {}
// This class implements GLES2Decoder so we don't have to expose all the GLES2
// cmd stuff to outside this class.
-class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient {
+class GLES2DecoderImpl : public GLES2Decoder,
+ public FramebufferManager::TextureDetachObserver,
+ public ErrorStateClient {
public:
explicit GLES2DecoderImpl(ContextGroup* group);
~GLES2DecoderImpl() override;
@@ -920,6 +965,9 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient {
error::ContextLostReason GetContextLostReason() override;
+ // Overridden from FramebufferManager::TextureDetachObserver:
+ void OnTextureRefDetachedFromFramebuffer(TextureRef* texture) override;
+
// Overriden from ErrorStateClient.
void OnContextLostError() override;
void OnOutOfMemoryError() override;
@@ -1921,13 +1969,10 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient {
const char* function_name, GLuint max_vertex_accessed, bool* simulated);
void RestoreStateForAttrib(GLuint attrib, bool restore_array_binding);
- // Copies the image to the texture currently bound to |textarget|. The image
- // state of |texture| is updated to reflect the new state.
- void DoCopyTexImage(Texture* texture, GLenum textarget, gfx::GLImage* image);
-
- // This will call DoCopyTexImage if texture has an image but that image is
- // not bound or copied to the texture.
- void DoCopyTexImageIfNeeded(Texture* texture, GLenum textarget);
+ // If an image is bound to texture, this will call Will/DidUseTexImage
+ // if needed.
+ void DoWillUseTexImageIfNeeded(Texture* texture, GLenum textarget);
+ void DoDidUseTexImageIfNeeded(Texture* texture, GLenum textarget);
// Returns false if textures were replaced.
bool PrepareTexturesForRender();
@@ -3247,6 +3292,8 @@ bool GLES2DecoderImpl::Initialize(
return false;
}
+ framebuffer_manager()->AddObserver(this);
+
return true;
}
@@ -4346,6 +4393,7 @@ void GLES2DecoderImpl::Destroy(bool have_context) {
}
if (group_.get()) {
+ framebuffer_manager()->RemoveObserver(this);
group_->Destroy(this, have_context);
group_ = NULL;
}
@@ -5189,6 +5237,7 @@ void GLES2DecoderImpl::DoDiscardFramebufferEXT(GLenum target,
translated_attachments[i] = attachment;
}
+ ScopedRenderTo do_render(framebuffer);
if (feature_info_->gl_version_info().is_es3) {
glInvalidateFramebuffer(
target, numAttachments, translated_attachments.get());
@@ -5966,6 +6015,7 @@ error::Error GLES2DecoderImpl::DoClear(GLbitfield mask) {
ApplyDirtyState();
// TODO(zmo): Filter out INTEGER/SIGNED INTEGER images to avoid
// undefined results.
+ ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
if (workarounds().gl_clear_broken) {
ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::ClearWorkaround",
GetErrorState());
@@ -5999,6 +6049,7 @@ void GLES2DecoderImpl::DoClearBufferiv(
GL_INVALID_ENUM, "glClearBufferiv", "invalid buffer");
return;
}
+ GLenum attachment = 0;
if (buffer == GL_COLOR) {
if (drawbuffer < 0 ||
drawbuffer >= static_cast<GLint>(group_->max_draw_buffers())) {
@@ -6012,6 +6063,7 @@ void GLES2DecoderImpl::DoClearBufferiv(
// To avoid undefined results, return without calling the gl function.
return;
}
+ attachment = static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + drawbuffer);
} else {
DCHECK(buffer == GL_STENCIL);
if (drawbuffer != 0) {
@@ -6022,9 +6074,14 @@ void GLES2DecoderImpl::DoClearBufferiv(
if (!BoundFramebufferHasStencilAttachment()) {
return;
}
+ attachment = GL_STENCIL_ATTACHMENT;
}
MarkDrawBufferAsCleared(buffer, drawbuffer);
- glClearBufferiv(buffer, drawbuffer, value);
+ {
+ ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get(),
+ attachment);
+ glClearBufferiv(buffer, drawbuffer, value);
+ }
}
void GLES2DecoderImpl::DoClearBufferuiv(
@@ -6054,7 +6111,12 @@ void GLES2DecoderImpl::DoClearBufferuiv(
return;
}
MarkDrawBufferAsCleared(buffer, drawbuffer);
- glClearBufferuiv(buffer, drawbuffer, value);
+ GLenum attachment = static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + drawbuffer);
+ {
+ ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get(),
+ attachment);
+ glClearBufferuiv(buffer, drawbuffer, value);
+ }
}
void GLES2DecoderImpl::DoClearBufferfv(
@@ -6072,6 +6134,7 @@ void GLES2DecoderImpl::DoClearBufferfv(
GL_INVALID_ENUM, "glClearBufferfv", "invalid buffer");
return;
}
+ GLenum attachment = 0;
if (buffer == GL_COLOR) {
if (drawbuffer < 0 ||
drawbuffer >= static_cast<GLint>(group_->max_draw_buffers())) {
@@ -6085,6 +6148,7 @@ void GLES2DecoderImpl::DoClearBufferfv(
// To avoid undefined results, return without calling the gl function.
return;
}
+ attachment = static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + drawbuffer);
} else {
DCHECK(buffer == GL_DEPTH);
if (drawbuffer != 0) {
@@ -6095,9 +6159,14 @@ void GLES2DecoderImpl::DoClearBufferfv(
if (!BoundFramebufferHasDepthAttachment()) {
return;
}
+ attachment = GL_DEPTH_ATTACHMENT;
}
MarkDrawBufferAsCleared(buffer, drawbuffer);
- glClearBufferfv(buffer, drawbuffer, value);
+ {
+ ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get(),
+ attachment);
+ glClearBufferfv(buffer, drawbuffer, value);
+ }
}
void GLES2DecoderImpl::DoClearBufferfi(
@@ -6125,7 +6194,15 @@ void GLES2DecoderImpl::DoClearBufferfi(
}
MarkDrawBufferAsCleared(GL_DEPTH, drawbuffer);
MarkDrawBufferAsCleared(GL_STENCIL, drawbuffer);
- glClearBufferfi(buffer, drawbuffer, depth, stencil);
+ {
+ ScopedRenderTo do_render_depth(
+ framebuffer_state_.bound_draw_framebuffer.get(),
+ GL_DEPTH_ATTACHMENT);
+ ScopedRenderTo do_render_stencil(
+ framebuffer_state_.bound_draw_framebuffer.get(),
+ GL_STENCIL_ATTACHMENT);
+ glClearBufferfi(buffer, drawbuffer, depth, stencil);
+ }
}
void GLES2DecoderImpl::DoFramebufferRenderbuffer(
@@ -6336,7 +6413,7 @@ void GLES2DecoderImpl::DoFramebufferTexture2DCommon(
}
if (texture_ref)
- DoCopyTexImageIfNeeded(texture_ref->texture(), textarget);
+ DoWillUseTexImageIfNeeded(texture_ref->texture(), textarget);
LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(name);
if (0 == samples) {
@@ -6359,6 +6436,9 @@ void GLES2DecoderImpl::DoFramebufferTexture2DCommon(
framebuffer_state_.clear_state_dirty = true;
}
+ if (texture_ref)
+ DoDidUseTexImageIfNeeded(texture_ref->texture(), textarget);
+
OnFboChanged();
}
@@ -6498,6 +6578,7 @@ void GLES2DecoderImpl::DoBlitFramebufferCHROMIUM(
}
state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
+ ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
BlitFramebufferHelper(
srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
state_.SetDeviceCapabilityState(GL_SCISSOR_TEST,
@@ -7557,29 +7638,33 @@ void GLES2DecoderImpl::PerformanceWarning(
std::string("PERFORMANCE WARNING: ") + msg);
}
-void GLES2DecoderImpl::DoCopyTexImage(Texture* texture,
- GLenum textarget,
- gfx::GLImage* image) {
- // Note: We update the state to COPIED prior to calling CopyTexImage()
- // as that allows the GLImage implemenatation to set it back to UNBOUND
- // and ensure that CopyTexImage() is called each time the texture is
- // used.
- texture->SetLevelImage(textarget, 0, image, Texture::COPIED);
- bool rv = image->CopyTexImage(textarget);
- DCHECK(rv) << "Both BindTexImage() and CopyTexImage() failed";
+void GLES2DecoderImpl::DoWillUseTexImageIfNeeded(
+ Texture* texture, GLenum textarget) {
+ // Image is already in use if texture is attached to a framebuffer.
+ if (texture && !texture->IsAttachedToFramebuffer()) {
+ gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
+ if (image) {
+ ScopedGLErrorSuppressor suppressor(
+ "GLES2DecoderImpl::DoWillUseTexImageIfNeeded",
+ GetErrorState());
+ glBindTexture(textarget, texture->service_id());
+ image->WillUseTexImage();
+ RestoreCurrentTextureBindings(&state_, textarget);
+ }
+ }
}
-void GLES2DecoderImpl::DoCopyTexImageIfNeeded(Texture* texture,
- GLenum textarget) {
- // Image is already in use if texture is attached to a framebuffer.
+void GLES2DecoderImpl::DoDidUseTexImageIfNeeded(
+ Texture* texture, GLenum textarget) {
+ // Image is still in use if texture is attached to a framebuffer.
if (texture && !texture->IsAttachedToFramebuffer()) {
- Texture::ImageState image_state;
- gfx::GLImage* image = texture->GetLevelImage(textarget, 0, &image_state);
- if (image && image_state == Texture::UNBOUND) {
+ gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
+ if (image) {
ScopedGLErrorSuppressor suppressor(
- "GLES2DecoderImpl::DoCopyTexImageIfNeeded", GetErrorState());
+ "GLES2DecoderImpl::DoDidUseTexImageIfNeeded",
+ GetErrorState());
glBindTexture(textarget, texture->service_id());
- DoCopyTexImage(texture, textarget, image);
+ image->DidUseTexImage();
RestoreCurrentTextureBindings(&state_, textarget);
}
}
@@ -7627,16 +7712,13 @@ bool GLES2DecoderImpl::PrepareTexturesForRender() {
if (textarget != GL_TEXTURE_CUBE_MAP) {
Texture* texture = texture_ref->texture();
- Texture::ImageState image_state;
- gfx::GLImage* image =
- texture->GetLevelImage(textarget, 0, &image_state);
- if (image && image_state == Texture::UNBOUND &&
- !texture->IsAttachedToFramebuffer()) {
+ gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
+ if (image && !texture->IsAttachedToFramebuffer()) {
ScopedGLErrorSuppressor suppressor(
"GLES2DecoderImpl::PrepareTexturesForRender", GetErrorState());
textures_set = true;
glActiveTexture(GL_TEXTURE0 + texture_unit_index);
- DoCopyTexImage(texture, textarget, image);
+ image->WillUseTexImage();
continue;
}
}
@@ -7671,6 +7753,19 @@ void GLES2DecoderImpl::RestoreStateForTextures() {
texture_ref ? texture_ref->service_id() : 0);
continue;
}
+
+ if (texture_unit.bind_target != GL_TEXTURE_CUBE_MAP) {
+ Texture* texture = texture_ref->texture();
+ gfx::GLImage* image =
+ texture->GetLevelImage(texture_unit.bind_target, 0);
+ if (image && !texture->IsAttachedToFramebuffer()) {
+ ScopedGLErrorSuppressor suppressor(
+ "GLES2DecoderImpl::RestoreStateForTextures", GetErrorState());
+ glActiveTexture(GL_TEXTURE0 + texture_unit_index);
+ image->DidUseTexImage();
+ continue;
+ }
+ }
}
}
}
@@ -8026,6 +8121,7 @@ error::Error GLES2DecoderImpl::DoDrawArrays(
primcount)) {
bool textures_set = !PrepareTexturesForRender();
ApplyDirtyState();
+ ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
if (!instanced) {
glDrawArrays(mode, first, count);
} else {
@@ -8162,6 +8258,7 @@ error::Error GLES2DecoderImpl::DoDrawElements(
indices = element_array_buffer->GetRange(offset, 0);
}
+ ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
if (!instanced) {
glDrawElements(mode, count, type, indices);
} else {
@@ -9392,10 +9489,9 @@ error::Error GLES2DecoderImpl::HandleScheduleOverlayPlaneCHROMIUM(
"unknown texture");
return error::kNoError;
}
- Texture::ImageState image_state;
gfx::GLImage* image =
- ref->texture()->GetLevelImage(ref->texture()->target(), 0, &image_state);
- if (!image || image_state != Texture::BOUND) {
+ ref->texture()->GetLevelImage(ref->texture()->target(), 0);
+ if (!image) {
LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
"glScheduleOverlayPlaneCHROMIUM",
"unsupported texture format");
@@ -10999,6 +11095,7 @@ void GLES2DecoderImpl::DoCopyTexImage2D(
// some part was clipped so clear the rect.
scoped_ptr<char[]> zero(new char[pixels_size]);
memset(zero.get(), 0, pixels_size);
+ ScopedModifyPixels modify(texture_ref);
glTexImage2D(target, level, internal_format, width, height, border,
format, type, zero.get());
if (copyHeight > 0 && copyWidth > 0) {
@@ -11011,6 +11108,7 @@ void GLES2DecoderImpl::DoCopyTexImage2D(
copyWidth, copyHeight);
}
} else {
+ ScopedModifyPixels modify(texture_ref);
glCopyTexImage2D(target, level, internal_format,
copyX, copyY, copyWidth, copyHeight, border);
}
@@ -11137,6 +11235,7 @@ void GLES2DecoderImpl::DoCopyTexSubImage2D(
}
scoped_ptr<char[]> zero(new char[pixels_size]);
memset(zero.get(), 0, pixels_size);
+ ScopedModifyPixels modify(texture_ref);
glTexSubImage2D(
target, level, xoffset, yoffset, width, height,
format, type, zero.get());
@@ -11147,6 +11246,7 @@ void GLES2DecoderImpl::DoCopyTexSubImage2D(
GLint dy = copyY - y;
GLint destX = xoffset + dx;
GLint destY = yoffset + dy;
+ ScopedModifyPixels modify(texture_ref);
glCopyTexSubImage2D(target, level,
destX, destY, copyX, copyY,
copyWidth, copyHeight);
@@ -13129,16 +13229,20 @@ void GLES2DecoderImpl::DoCopyTextureCHROMIUM(
true);
}
- // Try using GLImage::CopyTexImage when possible.
+ ScopedModifyPixels modify(dest_texture_ref);
+
+ // Try using GLImage::CopyTexSubImage when possible.
bool unpack_premultiply_alpha_change =
(unpack_premultiply_alpha ^ unpack_unmultiply_alpha) != 0;
if (image && !unpack_flip_y && !unpack_premultiply_alpha_change) {
glBindTexture(GL_TEXTURE_2D, dest_texture->service_id());
- if (image->CopyTexImage(GL_TEXTURE_2D))
+ if (image->CopyTexSubImage(GL_TEXTURE_2D, gfx::Point(0, 0),
+ gfx::Rect(0, 0, source_width, source_height))) {
return;
+ }
}
- DoCopyTexImageIfNeeded(source_texture, source_texture->target());
+ DoWillUseTexImageIfNeeded(source_texture, source_texture->target());
// GL_TEXTURE_EXTERNAL_OES texture requires apply a transform matrix
// before presenting.
@@ -13161,6 +13265,8 @@ void GLES2DecoderImpl::DoCopyTextureCHROMIUM(
unpack_premultiply_alpha == GL_TRUE,
unpack_unmultiply_alpha == GL_TRUE);
}
+
+ DoDidUseTexImageIfNeeded(source_texture, source_texture->target());
}
void GLES2DecoderImpl::DoCopySubTextureCHROMIUM(
@@ -13293,6 +13399,8 @@ void GLES2DecoderImpl::DoCopySubTextureCHROMIUM(
true);
}
+ ScopedModifyPixels modify(dest_texture_ref);
+
// Try using GLImage::CopyTexSubImage when possible.
bool unpack_premultiply_alpha_change =
(unpack_premultiply_alpha ^ unpack_unmultiply_alpha) != 0;
@@ -13305,7 +13413,7 @@ void GLES2DecoderImpl::DoCopySubTextureCHROMIUM(
}
}
- DoCopyTexImageIfNeeded(source_texture, source_texture->target());
+ DoWillUseTexImageIfNeeded(source_texture, source_texture->target());
// TODO(hkuang): get the StreamTexture transform matrix in GPU process.
// crbug.com/226218.
@@ -13317,6 +13425,8 @@ void GLES2DecoderImpl::DoCopySubTextureCHROMIUM(
unpack_flip_y == GL_TRUE,
unpack_premultiply_alpha == GL_TRUE,
unpack_unmultiply_alpha == GL_TRUE);
+
+ DoDidUseTexImageIfNeeded(source_texture, source_texture->target());
}
void GLES2DecoderImpl::DoCompressedCopyTextureCHROMIUM(GLenum target,
@@ -13402,6 +13512,8 @@ void GLES2DecoderImpl::DoCompressedCopyTextureCHROMIUM(GLenum target,
ScopedTextureBinder binder(
&state_, dest_texture->service_id(), GL_TEXTURE_2D);
+ ScopedModifyPixels modify(dest_texture_ref);
+
// Try using GLImage::CopyTexImage when possible.
if (image) {
GLenum dest_type = 0;
@@ -13447,15 +13559,17 @@ void GLES2DecoderImpl::DoCompressedCopyTextureCHROMIUM(GLenum target,
true);
}
- if (image->CopyTexImage(GL_TEXTURE_2D))
+ if (image->CopyTexSubImage(GL_TEXTURE_2D, gfx::Point(0, 0),
+ gfx::Rect(0, 0, source_width, source_height))) {
return;
+ }
}
TRACE_EVENT0(
"gpu",
"GLES2DecoderImpl::DoCompressedCopyTextureCHROMIUM, fallback");
- DoCopyTexImageIfNeeded(source_texture, source_texture->target());
+ DoWillUseTexImageIfNeeded(source_texture, source_texture->target());
// As a fallback, copy into a non-compressed GL_RGBA texture.
LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedCopyTextureCHROMIUM");
@@ -13487,6 +13601,8 @@ void GLES2DecoderImpl::DoCompressedCopyTextureCHROMIUM(GLenum target,
source_internal_format, dest_texture->service_id(), GL_RGBA,
source_width, source_height, false, false, false);
}
+
+ DoDidUseTexImageIfNeeded(source_texture, source_texture->target());
}
void GLES2DecoderImpl::DoCompressedCopySubTextureCHROMIUM(GLenum target,
@@ -13635,18 +13751,21 @@ void GLES2DecoderImpl::DoCompressedCopySubTextureCHROMIUM(GLenum target,
ScopedTextureBinder binder(
&state_, dest_texture->service_id(), GL_TEXTURE_2D);
+ ScopedModifyPixels modify(dest_texture_ref);
+
// Try using GLImage::CopyTexSubImage when possible.
- if (image &&
- image->CopyTexSubImage(GL_TEXTURE_2D, gfx::Point(xoffset, yoffset),
- gfx::Rect(x, y, width, height))) {
- return;
+ if (image) {
+ if (image->CopyTexSubImage(GL_TEXTURE_2D, gfx::Point(xoffset, yoffset),
+ gfx::Rect(x, y, width, height))) {
+ return;
+ }
}
TRACE_EVENT0(
"gpu",
"GLES2DecoderImpl::DoCompressedCopySubTextureCHROMIUM, fallback");
- DoCopyTexImageIfNeeded(source_texture, source_texture->target());
+ DoWillUseTexImageIfNeeded(source_texture, source_texture->target());
// As a fallback, copy into a non-compressed GL_RGBA texture.
if (dest_internal_format != GL_RGBA) {
@@ -13699,6 +13818,8 @@ void GLES2DecoderImpl::DoCompressedCopySubTextureCHROMIUM(GLenum target,
source_internal_format, dest_texture->service_id(), GL_RGBA,
xoffset, yoffset, x, y, width, height, dest_width, dest_height,
source_width, source_height, false, false, false);
+
+ DoDidUseTexImageIfNeeded(source_texture, source_texture->target());
}
void GLES2DecoderImpl::DoTexStorage2DEXT(
@@ -14111,32 +14232,31 @@ void GLES2DecoderImpl::DoBindTexImage2DCHROMIUM(
return;
}
- gfx::GLImage* image = image_manager()->LookupImage(image_id);
- if (!image) {
+ gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
+ if (!gl_image) {
LOCAL_SET_GL_ERROR(
GL_INVALID_OPERATION,
"glBindTexImage2DCHROMIUM", "no image found with the given ID");
return;
}
- Texture::ImageState image_state = Texture::UNBOUND;
-
{
ScopedGLErrorSuppressor suppressor(
"GLES2DecoderImpl::DoBindTexImage2DCHROMIUM", GetErrorState());
-
- // Note: We fallback to using CopyTexImage() before the texture is used
- // when BindTexImage() fails.
- if (image->BindTexImage(target))
- image_state = Texture::BOUND;
+ if (!gl_image->BindTexImage(target)) {
+ LOCAL_SET_GL_ERROR(
+ GL_INVALID_OPERATION,
+ "glBindTexImage2DCHROMIUM", "fail to bind image with the given ID");
+ return;
+ }
}
- gfx::Size size = image->GetSize();
- GLenum internalformat = image->GetInternalFormat();
+ gfx::Size size = gl_image->GetSize();
texture_manager()->SetLevelInfo(
- texture_ref, target, 0, internalformat, size.width(), size.height(), 1, 0,
- internalformat, GL_UNSIGNED_BYTE, gfx::Rect(size));
- texture_manager()->SetLevelImage(texture_ref, target, 0, image, image_state);
+ texture_ref, target, 0, gl_image->GetInternalFormat(), size.width(),
+ size.height(), 1, 0, gl_image->GetInternalFormat(), GL_UNSIGNED_BYTE,
+ gfx::Rect(size));
+ texture_manager()->SetLevelImage(texture_ref, target, 0, gl_image);
}
void GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM(
@@ -14154,31 +14274,27 @@ void GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM(
return;
}
- gfx::GLImage* image = image_manager()->LookupImage(image_id);
- if (!image) {
+ gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
+ if (!gl_image) {
LOCAL_SET_GL_ERROR(
GL_INVALID_OPERATION,
"glReleaseTexImage2DCHROMIUM", "no image found with the given ID");
return;
}
- Texture::ImageState image_state;
-
// Do nothing when image is not currently bound.
- if (texture_ref->texture()->GetLevelImage(target, 0, &image_state) != image)
+ if (texture_ref->texture()->GetLevelImage(target, 0) != gl_image)
return;
- if (image_state == Texture::BOUND) {
+ {
ScopedGLErrorSuppressor suppressor(
"GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM", GetErrorState());
-
- image->ReleaseTexImage(target);
- texture_manager()->SetLevelInfo(texture_ref, target, 0, GL_RGBA, 0, 0, 1, 0,
- GL_RGBA, GL_UNSIGNED_BYTE, gfx::Rect());
+ gl_image->ReleaseTexImage(target);
}
- texture_manager()->SetLevelImage(texture_ref, target, 0, nullptr,
- Texture::UNBOUND);
+ texture_manager()->SetLevelInfo(
+ texture_ref, target, 0, gl_image->GetInternalFormat(), 0, 0, 1, 0,
+ gl_image->GetInternalFormat(), GL_UNSIGNED_BYTE, gfx::Rect());
}
error::Error GLES2DecoderImpl::HandleTraceBeginCHROMIUM(
@@ -14533,6 +14649,12 @@ error::Error GLES2DecoderImpl::HandleUnmapBuffer(
return error::kNoError;
}
+void GLES2DecoderImpl::OnTextureRefDetachedFromFramebuffer(
+ TextureRef* texture_ref) {
+ Texture* texture = texture_ref->texture();
+ DoDidUseTexImageIfNeeded(texture, texture->target());
+}
+
// Note that GL_LOST_CONTEXT is specific to GLES.
// For desktop GL we have to query the reset status proactively.
void GLES2DecoderImpl::OnContextLostError() {
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc
index 4a8f9cf..89dec15 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc
@@ -2830,9 +2830,12 @@ 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_METHOD3(CopyTexSubImage,
bool(unsigned, const gfx::Point&, const gfx::Rect&));
+ MOCK_METHOD0(WillUseTexImage, void());
+ MOCK_METHOD0(DidUseTexImage, void());
+ MOCK_METHOD0(WillModifyTexImage, void());
+ MOCK_METHOD0(DidModifyTexImage, void());
MOCK_METHOD5(ScheduleOverlayPlane, bool(gfx::AcceleratedWidget,
int,
gfx::OverlayTransform,
@@ -2847,7 +2850,7 @@ class MockGLImage : public gfx::GLImage {
virtual ~MockGLImage() {}
};
-TEST_P(GLES2DecoderWithShaderTest, CopyTexImage) {
+TEST_P(GLES2DecoderWithShaderTest, UseTexImage) {
DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
DoTexImage2D(GL_TEXTURE_2D,
0,
@@ -2873,16 +2876,12 @@ TEST_P(GLES2DecoderWithShaderTest, CopyTexImage) {
// Bind image to texture.
EXPECT_CALL(*image.get(), BindTexImage(GL_TEXTURE_2D))
.Times(1)
- .WillOnce(Return(false))
+ .WillOnce(Return(true))
.RetiresOnSaturation();
EXPECT_CALL(*image.get(), GetSize())
.Times(1)
.WillOnce(Return(gfx::Size(1, 1)))
.RetiresOnSaturation();
- EXPECT_CALL(*image.get(), GetInternalFormat())
- .Times(1)
- .WillOnce(Return(GL_RGBA))
- .RetiresOnSaturation();
// ScopedGLErrorSuppressor calls GetError on its constructor and destructor.
DoBindTexImage2DCHROMIUM(GL_TEXTURE_2D, kImageId);
@@ -2893,12 +2892,12 @@ TEST_P(GLES2DecoderWithShaderTest, CopyTexImage) {
EXPECT_CALL(*gl_, GetError())
.WillOnce(Return(GL_NO_ERROR))
.WillOnce(Return(GL_NO_ERROR))
+ .WillOnce(Return(GL_NO_ERROR))
+ .WillOnce(Return(GL_NO_ERROR))
.RetiresOnSaturation();
- EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE0)).Times(2).RetiresOnSaturation();
- EXPECT_CALL(*image.get(), CopyTexImage(GL_TEXTURE_2D))
- .Times(1)
- .WillOnce(Return(true))
- .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE0)).Times(3).RetiresOnSaturation();
+ EXPECT_CALL(*image.get(), WillUseTexImage()).Times(1).RetiresOnSaturation();
+ EXPECT_CALL(*image.get(), DidUseTexImage()).Times(1).RetiresOnSaturation();
EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
.Times(1)
.RetiresOnSaturation();
@@ -2907,25 +2906,6 @@ TEST_P(GLES2DecoderWithShaderTest, CopyTexImage) {
EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
EXPECT_EQ(GL_NO_ERROR, GetGLError());
- DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
- // Re-bind image to texture.
- ReleaseTexImage2DCHROMIUM release_tex_image_2d_cmd;
- release_tex_image_2d_cmd.Init(GL_TEXTURE_2D, kImageId);
- EXPECT_EQ(error::kNoError, ExecuteCmd(release_tex_image_2d_cmd));
- EXPECT_CALL(*image.get(), BindTexImage(GL_TEXTURE_2D))
- .Times(1)
- .WillOnce(Return(false))
- .RetiresOnSaturation();
- EXPECT_CALL(*image.get(), GetSize())
- .Times(1)
- .WillOnce(Return(gfx::Size(1, 1)))
- .RetiresOnSaturation();
- EXPECT_CALL(*image.get(), GetInternalFormat())
- .Times(1)
- .WillOnce(Return(GL_RGBA))
- .RetiresOnSaturation();
- DoBindTexImage2DCHROMIUM(GL_TEXTURE_2D, kImageId);
-
DoBindFramebuffer(
GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
// ScopedGLErrorSuppressor calls GetError on its constructor and destructor.
@@ -2937,10 +2917,8 @@ TEST_P(GLES2DecoderWithShaderTest, CopyTexImage) {
EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, kServiceTextureId))
.Times(2)
.RetiresOnSaturation();
- EXPECT_CALL(*image.get(), CopyTexImage(GL_TEXTURE_2D))
- .Times(1)
- .WillOnce(Return(true))
- .RetiresOnSaturation();
+ // Image will be 'in use' as long as bound to a framebuffer.
+ EXPECT_CALL(*image.get(), WillUseTexImage()).Times(1).RetiresOnSaturation();
EXPECT_CALL(*gl_,
FramebufferTexture2DEXT(GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
@@ -2961,8 +2939,34 @@ TEST_P(GLES2DecoderWithShaderTest, CopyTexImage) {
EXPECT_EQ(error::kNoError, ExecuteCmd(fbtex_cmd));
EXPECT_EQ(GL_NO_ERROR, GetGLError());
- EXPECT_CALL(*image.get(), Destroy(true)).Times(1).RetiresOnSaturation();
- image = nullptr;
+ // ScopedGLErrorSuppressor calls GetError on its constructor and destructor.
+ EXPECT_CALL(*gl_, GetError())
+ .WillOnce(Return(GL_NO_ERROR))
+ .WillOnce(Return(GL_NO_ERROR))
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_,
+ FramebufferRenderbufferEXT(GL_FRAMEBUFFER,
+ GL_COLOR_ATTACHMENT0,
+ GL_RENDERBUFFER,
+ kServiceRenderbufferId))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE0)).Times(1).RetiresOnSaturation();
+ EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, kServiceTextureId))
+ .Times(2)
+ .RetiresOnSaturation();
+ // Image should no longer be 'in use' after being unbound from framebuffer.
+ EXPECT_CALL(*image.get(), DidUseTexImage()).Times(1).RetiresOnSaturation();
+ EXPECT_CALL(*gl_, GetError())
+ .WillOnce(Return(GL_NO_ERROR))
+ .WillOnce(Return(GL_NO_ERROR))
+ .RetiresOnSaturation();
+ FramebufferRenderbuffer fbrb_cmd;
+ fbrb_cmd.Init(GL_FRAMEBUFFER,
+ GL_COLOR_ATTACHMENT0,
+ GL_RENDERBUFFER,
+ client_renderbuffer_id_);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(fbrb_cmd));
}
TEST_P(GLES2DecoderManualInitTest, DrawWithGLImageExternal) {
@@ -2982,8 +2986,8 @@ TEST_P(GLES2DecoderManualInitTest, DrawWithGLImageExternal) {
group().texture_manager()->SetLevelInfo(texture_ref, GL_TEXTURE_EXTERNAL_OES,
0, GL_RGBA, 0, 0, 1, 0, GL_RGBA,
GL_UNSIGNED_BYTE, gfx::Rect());
- group().texture_manager()->SetLevelImage(texture_ref, GL_TEXTURE_EXTERNAL_OES,
- 0, image.get(), Texture::BOUND);
+ group().texture_manager()->SetLevelImage(
+ texture_ref, GL_TEXTURE_EXTERNAL_OES, 0, image.get());
DoBindTexture(GL_TEXTURE_EXTERNAL_OES, client_texture_id_, kServiceTextureId);
EXPECT_EQ(GL_NO_ERROR, GetGLError());
@@ -2995,7 +2999,24 @@ TEST_P(GLES2DecoderManualInitTest, DrawWithGLImageExternal) {
EXPECT_TRUE(group().texture_manager()->CanRender(texture_ref));
InSequence s;
+ EXPECT_CALL(*gl_, GetError())
+ .WillOnce(Return(GL_NO_ERROR))
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE0)).Times(1).RetiresOnSaturation();
+ EXPECT_CALL(*image.get(), WillUseTexImage()).Times(1).RetiresOnSaturation();
+ EXPECT_CALL(*gl_, GetError())
+ .WillOnce(Return(GL_NO_ERROR))
+ .RetiresOnSaturation();
EXPECT_CALL(*gl_, DrawElements(_, _, _, _)).Times(1);
+ EXPECT_CALL(*gl_, GetError())
+ .WillOnce(Return(GL_NO_ERROR))
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE0)).Times(1).RetiresOnSaturation();
+ EXPECT_CALL(*image.get(), DidUseTexImage()).Times(1).RetiresOnSaturation();
+ EXPECT_CALL(*gl_, GetError())
+ .WillOnce(Return(GL_NO_ERROR))
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE0)).Times(1).RetiresOnSaturation();
DrawElements cmd;
cmd.Init(GL_TRIANGLES,
kValidIndexRangeCount,
diff --git a/gpu/command_buffer/service/mailbox_manager_sync.cc b/gpu/command_buffer/service/mailbox_manager_sync.cc
index a48d032..7463f92 100644
--- a/gpu/command_buffer/service/mailbox_manager_sync.cc
+++ b/gpu/command_buffer/service/mailbox_manager_sync.cc
@@ -273,7 +273,7 @@ void MailboxManagerSync::UpdateDefinitionLocked(
if (SkipTextureWorkarounds(texture))
return;
- gfx::GLImage* image = texture->GetLevelImage(texture->target(), 0);
+ gfx::GLImage* gl_image = texture->GetLevelImage(texture->target(), 0);
TextureGroup* group = group_ref->group.get();
const TextureDefinition& definition = group->GetDefinition();
scoped_refptr<NativeImageBuffer> image_buffer = definition.image();
@@ -287,14 +287,14 @@ void MailboxManagerSync::UpdateDefinitionLocked(
if (definition.Matches(texture))
return;
- DCHECK_IMPLIES(image, image_buffer.get());
- if (image && !image_buffer->IsClient(image)) {
+ DCHECK_IMPLIES(gl_image, image_buffer.get());
+ if (gl_image && !image_buffer->IsClient(gl_image)) {
LOG(ERROR) << "MailboxSync: Incompatible attachment";
return;
}
group->SetDefinition(TextureDefinition(texture, ++group_ref->version,
- image ? image_buffer : NULL));
+ gl_image ? image_buffer : NULL));
}
void MailboxManagerSync::PushTextureUpdates(const SyncToken& token) {
diff --git a/gpu/command_buffer/service/stream_texture_manager_in_process_android.cc b/gpu/command_buffer/service/stream_texture_manager_in_process_android.cc
index 0883f75..e7e3a1f 100644
--- a/gpu/command_buffer/service/stream_texture_manager_in_process_android.cc
+++ b/gpu/command_buffer/service/stream_texture_manager_in_process_android.cc
@@ -19,9 +19,7 @@ namespace {
// Simply wraps a SurfaceTexture reference as a GLImage.
class GLImageImpl : public gfx::GLImage {
public:
- GLImageImpl(uint32 texture_id,
- gles2::TextureManager* texture_manager,
- const scoped_refptr<gfx::SurfaceTexture>& surface_texture,
+ GLImageImpl(const scoped_refptr<gfx::SurfaceTexture>& surface_texture,
const base::Closure& release_callback);
// implement gfx::GLImage
@@ -30,10 +28,13 @@ class GLImageImpl : public gfx::GLImage {
unsigned GetInternalFormat() override;
bool BindTexImage(unsigned target) override;
void ReleaseTexImage(unsigned target) override;
- bool CopyTexImage(unsigned target) override;
bool CopyTexSubImage(unsigned target,
const gfx::Point& offset,
const gfx::Rect& rect) override;
+ void WillUseTexImage() override;
+ void DidUseTexImage() override {}
+ void WillModifyTexImage() override {}
+ void DidModifyTexImage() override {}
bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
int z_order,
gfx::OverlayTransform transform,
@@ -46,8 +47,6 @@ class GLImageImpl : public gfx::GLImage {
private:
~GLImageImpl() override;
- uint32 texture_id_;
- gles2::TextureManager* texture_manager_;
scoped_refptr<gfx::SurfaceTexture> surface_texture_;
base::Closure release_callback_;
@@ -55,14 +54,9 @@ class GLImageImpl : public gfx::GLImage {
};
GLImageImpl::GLImageImpl(
- uint32 texture_id,
- gles2::TextureManager* texture_manager,
const scoped_refptr<gfx::SurfaceTexture>& surface_texture,
const base::Closure& release_callback)
- : texture_id_(texture_id),
- texture_manager_(texture_manager),
- surface_texture_(surface_texture),
- release_callback_(release_callback) {}
+ : surface_texture_(surface_texture), release_callback_(release_callback) {}
GLImageImpl::~GLImageImpl() {
release_callback_.Run();
@@ -89,27 +83,16 @@ void GLImageImpl::ReleaseTexImage(unsigned target) {
NOTREACHED();
}
-bool GLImageImpl::CopyTexImage(unsigned target) {
- surface_texture_->UpdateTexImage();
-
- gles2::Texture* texture =
- texture_manager_->GetTextureForServiceId(texture_id_);
- if (texture) {
- // By setting image state to UNBOUND instead of COPIED we ensure that
- // CopyTexImage() is called each time the surface texture is used for
- // drawing.
- texture->SetLevelImage(GL_TEXTURE_EXTERNAL_OES, 0, this,
- gles2::Texture::UNBOUND);
- }
- return true;
-}
-
bool GLImageImpl::CopyTexSubImage(unsigned target,
const gfx::Point& offset,
const gfx::Rect& rect) {
return false;
}
+void GLImageImpl::WillUseTexImage() {
+ surface_texture_->UpdateTexImage();
+}
+
bool GLImageImpl::ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
int z_order,
gfx::OverlayTransform transform,
@@ -156,17 +139,16 @@ GLuint StreamTextureManagerInProcess::CreateStreamTexture(
base::Closure release_callback =
base::Bind(&StreamTextureManagerInProcess::OnReleaseStreamTexture,
weak_factory_.GetWeakPtr(), stream_id);
- scoped_refptr<gfx::GLImage> gl_image(
- new GLImageImpl(texture->service_id(), texture_manager, surface_texture,
- release_callback));
+ scoped_refptr<gfx::GLImage> gl_image(new GLImageImpl(surface_texture,
+ release_callback));
gfx::Size size = gl_image->GetSize();
texture_manager->SetTarget(texture, GL_TEXTURE_EXTERNAL_OES);
texture_manager->SetLevelInfo(texture, GL_TEXTURE_EXTERNAL_OES, 0, GL_RGBA,
size.width(), size.height(), 1, 0, GL_RGBA,
GL_UNSIGNED_BYTE, gfx::Rect(size));
- texture_manager->SetLevelImage(texture, GL_TEXTURE_EXTERNAL_OES, 0,
- gl_image.get(), gles2::Texture::UNBOUND);
+ texture_manager->SetLevelImage(
+ texture, GL_TEXTURE_EXTERNAL_OES, 0, gl_image.get());
{
base::AutoLock lock(map_lock_);
diff --git a/gpu/command_buffer/service/texture_definition.cc b/gpu/command_buffer/service/texture_definition.cc
index 38fd956..1f1372a 100644
--- a/gpu/command_buffer/service/texture_definition.cc
+++ b/gpu/command_buffer/service/texture_definition.cc
@@ -36,10 +36,13 @@ class GLImageSync : public gfx::GLImage {
unsigned GetInternalFormat() override;
bool BindTexImage(unsigned target) override;
void ReleaseTexImage(unsigned target) override;
- bool CopyTexImage(unsigned target) override;
bool CopyTexSubImage(unsigned target,
const gfx::Point& offset,
const gfx::Rect& rect) override;
+ void WillUseTexImage() override;
+ void WillModifyTexImage() override;
+ void DidModifyTexImage() override;
+ void DidUseTexImage() override;
bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
int z_order,
gfx::OverlayTransform transform,
@@ -91,18 +94,24 @@ void GLImageSync::ReleaseTexImage(unsigned target) {
NOTREACHED();
}
-bool GLImageSync::CopyTexImage(unsigned target) {
- NOTREACHED();
- return false;
-}
-
bool GLImageSync::CopyTexSubImage(unsigned target,
const gfx::Point& offset,
const gfx::Rect& rect) {
- NOTREACHED();
return false;
}
+void GLImageSync::WillUseTexImage() {
+}
+
+void GLImageSync::DidUseTexImage() {
+}
+
+void GLImageSync::WillModifyTexImage() {
+}
+
+void GLImageSync::DidModifyTexImage() {
+}
+
bool GLImageSync::ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
int z_order,
gfx::OverlayTransform transform,
@@ -348,7 +357,7 @@ TextureDefinition::TextureDefinition(
new GLImageSync(image_buffer_,
gfx::Size(first_face.level_infos[0].width,
first_face.level_infos[0].height)));
- texture->SetLevelImage(target_, 0, gl_image.get(), Texture::BOUND);
+ texture->SetLevelImage(NULL, target_, 0, gl_image.get());
}
const Texture::LevelInfo& level = first_face.level_infos[0];
@@ -397,10 +406,12 @@ void TextureDefinition::UpdateTextureInternal(Texture* texture) const {
if (image_buffer_.get()) {
texture->SetLevelImage(
- target_, 0,
- new GLImageSync(image_buffer_,
- gfx::Size(level_info_.width, level_info_.height)),
- Texture::BOUND);
+ NULL,
+ target_,
+ 0,
+ new GLImageSync(
+ image_buffer_,
+ gfx::Size(level_info_.width, level_info_.height)));
}
texture->target_ = target_;
@@ -426,7 +437,7 @@ void TextureDefinition::UpdateTexture(Texture* texture) const {
if (bound_id == static_cast<GLint>(old_service_id)) {
glBindTexture(target_, service_id);
}
- texture->SetLevelImage(target_, 0, NULL, Texture::UNBOUND);
+ texture->SetLevelImage(NULL, target_, 0, NULL);
}
UpdateTextureInternal(texture);
diff --git a/gpu/command_buffer/service/texture_manager.cc b/gpu/command_buffer/service/texture_manager.cc
index 4fb92c6..716bedc 100644
--- a/gpu/command_buffer/service/texture_manager.cc
+++ b/gpu/command_buffer/service/texture_manager.cc
@@ -392,8 +392,8 @@ Texture::LevelInfo::LevelInfo()
border(0),
format(0),
type(0),
- image_state(UNBOUND),
- estimated_size(0) {}
+ estimated_size(0) {
+}
Texture::LevelInfo::LevelInfo(const LevelInfo& rhs)
: cleared_rect(rhs.cleared_rect),
@@ -407,8 +407,8 @@ Texture::LevelInfo::LevelInfo(const LevelInfo& rhs)
format(rhs.format),
type(rhs.type),
image(rhs.image),
- image_state(rhs.image_state),
- estimated_size(rhs.estimated_size) {}
+ estimated_size(rhs.estimated_size) {
+}
Texture::LevelInfo::~LevelInfo() {
}
@@ -832,7 +832,6 @@ void Texture::SetLevelInfo(const FeatureInfo* feature_info,
info.format = format;
info.type = type;
info.image = 0;
- info.image_state = UNBOUND;
UpdateMipCleared(&info, width, height, cleared_rect);
@@ -1238,10 +1237,11 @@ bool Texture::ClearLevel(
return true;
}
-void Texture::SetLevelImage(GLenum target,
- GLint level,
- gfx::GLImage* image,
- ImageState state) {
+void Texture::SetLevelImage(
+ const FeatureInfo* feature_info,
+ GLenum target,
+ GLint level,
+ gfx::GLImage* image) {
DCHECK_GE(level, 0);
size_t face_index = GLES2Util::GLTargetToFaceIndex(target);
DCHECK_LT(static_cast<size_t>(face_index),
@@ -1253,14 +1253,15 @@ void Texture::SetLevelImage(GLenum target,
DCHECK_EQ(info.target, target);
DCHECK_EQ(info.level, level);
info.image = image;
- info.image_state = state;
UpdateCanRenderCondition();
UpdateHasImages();
+
+ // TODO(ericrk): Images may have complex sizing not accounted for by
+ // |estimated_size_|, we should add logic here to update |estimated_size_|
+ // based on the new GLImage. crbug.com/526298
}
-gfx::GLImage* Texture::GetLevelImage(GLint target,
- GLint level,
- ImageState* state) const {
+gfx::GLImage* Texture::GetLevelImage(GLint target, GLint level) const {
if (target != GL_TEXTURE_2D && target != GL_TEXTURE_EXTERNAL_OES &&
target != GL_TEXTURE_RECTANGLE_ARB) {
return NULL;
@@ -1271,16 +1272,22 @@ gfx::GLImage* Texture::GetLevelImage(GLint target,
static_cast<size_t>(level) < face_infos_[face_index].level_infos.size()) {
const LevelInfo& info = face_infos_[face_index].level_infos[level];
if (info.target != 0) {
- if (state)
- *state = info.image_state;
return info.image.get();
}
}
return NULL;
}
-gfx::GLImage* Texture::GetLevelImage(GLint target, GLint level) const {
- return GetLevelImage(target, level, nullptr);
+void Texture::OnWillModifyPixels() {
+ gfx::GLImage* image = GetLevelImage(target(), 0);
+ if (image)
+ image->WillModifyTexImage();
+}
+
+void Texture::OnDidModifyPixels() {
+ gfx::GLImage* image = GetLevelImage(target(), 0);
+ if (image)
+ image->DidModifyTexImage();
}
void Texture::DumpLevelMemory(base::trace_event::ProcessMemoryDump* pmd,
@@ -1295,18 +1302,14 @@ void Texture::DumpLevelMemory(base::trace_event::ProcessMemoryDump* pmd,
if (!level_infos[level_index].estimated_size)
continue;
- // If a level has a GLImage, ask the GLImage to dump itself.
if (level_infos[level_index].image) {
+ // If a level is backed by a GLImage, ask the GLImage to dump itself.
level_infos[level_index].image->OnMemoryDump(
pmd, client_tracing_id,
base::StringPrintf("%s/face_%d/level_%d", dump_name.c_str(),
face_index, level_index));
- }
-
- // If a level does not have a GLImage bound to it, then dump the
- // texture allocation also as the storage is not provided by the
- // GLImage in that case.
- if (level_infos[level_index].image_state != BOUND) {
+ } else {
+ // If a level is not backed by a GLImage, create a simple dump.
base::trace_event::MemoryAllocatorDump* dump = pmd->CreateAllocatorDump(
base::StringPrintf("%s/face_%d/level_%d", dump_name.c_str(),
face_index, level_index));
@@ -1722,13 +1725,13 @@ GLsizei TextureManager::ComputeMipMapCount(GLenum target,
}
}
-void TextureManager::SetLevelImage(TextureRef* ref,
- GLenum target,
- GLint level,
- gfx::GLImage* image,
- Texture::ImageState state) {
+void TextureManager::SetLevelImage(
+ TextureRef* ref,
+ GLenum target,
+ GLint level,
+ gfx::GLImage* image) {
DCHECK(ref);
- ref->texture()->SetLevelImage(target, level, image, state);
+ ref->texture()->SetLevelImage(feature_info_.get(), target, level, image);
}
size_t TextureManager::GetSignatureSize() const {
diff --git a/gpu/command_buffer/service/texture_manager.h b/gpu/command_buffer/service/texture_manager.h
index 33cd54a..a04cfa2 100644
--- a/gpu/command_buffer/service/texture_manager.h
+++ b/gpu/command_buffer/service/texture_manager.h
@@ -39,22 +39,6 @@ class TextureRef;
// jointly owned by possibly multiple TextureRef.
class GPU_EXPORT Texture {
public:
- enum ImageState {
- // If an image is associated with the texture and image state is UNBOUND,
- // then sampling out of the texture or using it as a target for drawing
- // will not read/write from/to the image.
- UNBOUND,
- // If image state is BOUND, then sampling from the texture will return the
- // contents of the image and using it as a target will modify the image.
- BOUND,
- // Image state is set to COPIED if the contents of the image has been
- // copied to the texture. Sampling from the texture will be equivalent
- // to sampling out the image (assuming image has not been changed since
- // it was copied). Using the texture as a target for drawing will only
- // modify the texture and not the image.
- COPIED
- };
-
explicit Texture(GLuint service_id);
GLenum min_filter() const {
@@ -149,17 +133,8 @@ class GPU_EXPORT Texture {
bool GetLevelType(
GLint target, GLint level, GLenum* type, GLenum* internal_format) const;
- // Set the image for a particular level.
- void SetLevelImage(GLenum target,
- GLint level,
- gfx::GLImage* image,
- ImageState state);
-
- // Get the image associated with a particular level. Returns NULL if level
+ // Get the image bound to a particular level. Returns NULL if level
// does not exist.
- gfx::GLImage* GetLevelImage(GLint target,
- GLint level,
- ImageState* state) const;
gfx::GLImage* GetLevelImage(GLint target, GLint level) const;
bool HasImages() const {
@@ -218,6 +193,9 @@ class GPU_EXPORT Texture {
// Initialize TEXTURE_MAX_ANISOTROPY to 1 if we haven't done so yet.
void InitTextureMaxAnisotropyIfNeeded(GLenum target);
+ void OnWillModifyPixels();
+ void OnDidModifyPixels();
+
void DumpLevelMemory(base::trace_event::ProcessMemoryDump* pmd,
uint64_t client_tracing_id,
const std::string& dump_name) const;
@@ -264,7 +242,6 @@ class GPU_EXPORT Texture {
GLenum format;
GLenum type;
scoped_refptr<gfx::GLImage> image;
- ImageState image_state;
uint32 estimated_size;
};
@@ -385,6 +362,13 @@ class GPU_EXPORT Texture {
// Update info about this texture.
void Update(const FeatureInfo* feature_info);
+ // Set the image for a particular level.
+ void SetLevelImage(
+ const FeatureInfo* feature_info,
+ GLenum target,
+ GLint level,
+ gfx::GLImage* image);
+
// Appends a signature for the given level.
void AddToSignature(
const FeatureInfo* feature_info,
@@ -806,11 +790,11 @@ class GPU_EXPORT TextureManager : public base::trace_event::MemoryDumpProvider {
return memory_type_tracker_->GetMemRepresented();
}
- void SetLevelImage(TextureRef* ref,
- GLenum target,
- GLint level,
- gfx::GLImage* image,
- Texture::ImageState state);
+ void SetLevelImage(
+ TextureRef* ref,
+ GLenum target,
+ GLint level,
+ gfx::GLImage* image);
size_t GetSignatureSize() const;
diff --git a/gpu/command_buffer/service/texture_manager_unittest.cc b/gpu/command_buffer/service/texture_manager_unittest.cc
index 516f478..90e90c4 100644
--- a/gpu/command_buffer/service/texture_manager_unittest.cc
+++ b/gpu/command_buffer/service/texture_manager_unittest.cc
@@ -1391,15 +1391,12 @@ TEST_F(TextureTest, GetLevelImage) {
EXPECT_TRUE(texture->GetLevelImage(GL_TEXTURE_2D, 1) == NULL);
// Set image.
scoped_refptr<gfx::GLImage> image(new gfx::GLImageStub);
- manager_->SetLevelImage(texture_ref_.get(), GL_TEXTURE_2D, 1, image.get(),
- Texture::BOUND);
+ manager_->SetLevelImage(texture_ref_.get(), GL_TEXTURE_2D, 1, image.get());
EXPECT_FALSE(texture->GetLevelImage(GL_TEXTURE_2D, 1) == NULL);
// Remove it.
- manager_->SetLevelImage(texture_ref_.get(), GL_TEXTURE_2D, 1, nullptr,
- Texture::UNBOUND);
+ manager_->SetLevelImage(texture_ref_.get(), GL_TEXTURE_2D, 1, NULL);
EXPECT_TRUE(texture->GetLevelImage(GL_TEXTURE_2D, 1) == NULL);
- manager_->SetLevelImage(texture_ref_.get(), GL_TEXTURE_2D, 1, image.get(),
- Texture::UNBOUND);
+ manager_->SetLevelImage(texture_ref_.get(), GL_TEXTURE_2D, 1, image.get());
// Image should be reset when SetLevelInfo is called.
manager_->SetLevelInfo(texture_ref_.get(), GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 1,
0, GL_RGBA, GL_UNSIGNED_BYTE, gfx::Rect(2, 2));
@@ -1740,8 +1737,7 @@ TEST_P(ProduceConsumeTextureTest, ProduceConsumeTextureWithImage) {
scoped_refptr<gfx::GLImage> image(new gfx::GLImageStub);
manager_->SetLevelInfo(texture_ref_.get(), target, 0, GL_RGBA, 0, 0, 1, 0,
GL_RGBA, GL_UNSIGNED_BYTE, gfx::Rect());
- manager_->SetLevelImage(texture_ref_.get(), target, 0, image.get(),
- Texture::BOUND);
+ manager_->SetLevelImage(texture_ref_.get(), target, 0, image.get());
GLuint service_id = texture->service_id();
Texture* produced_texture = Produce(texture_ref_.get());
@@ -2061,15 +2057,13 @@ TEST_F(SharedTextureTest, Images) {
EXPECT_FALSE(texture_manager1_->HaveImages());
EXPECT_FALSE(texture_manager2_->HaveImages());
scoped_refptr<gfx::GLImage> image1(new gfx::GLImageStub);
- texture_manager1_->SetLevelImage(ref1.get(), GL_TEXTURE_2D, 1, image1.get(),
- Texture::BOUND);
+ texture_manager1_->SetLevelImage(ref1.get(), GL_TEXTURE_2D, 1, image1.get());
EXPECT_TRUE(ref1->texture()->HasImages());
EXPECT_TRUE(ref2->texture()->HasImages());
EXPECT_TRUE(texture_manager1_->HaveImages());
EXPECT_TRUE(texture_manager2_->HaveImages());
scoped_refptr<gfx::GLImage> image2(new gfx::GLImageStub);
- texture_manager1_->SetLevelImage(ref1.get(), GL_TEXTURE_2D, 1, image2.get(),
- Texture::BOUND);
+ texture_manager1_->SetLevelImage(ref1.get(), GL_TEXTURE_2D, 1, image2.get());
EXPECT_TRUE(ref1->texture()->HasImages());
EXPECT_TRUE(ref2->texture()->HasImages());
EXPECT_TRUE(texture_manager1_->HaveImages());
diff --git a/ui/gl/BUILD.gn b/ui/gl/BUILD.gn
index 2e04ee0..bfd095b 100644
--- a/ui/gl/BUILD.gn
+++ b/ui/gl/BUILD.gn
@@ -356,7 +356,6 @@ test("gl_unittests") {
"//testing/gmock",
"//testing/gtest",
"//ui/gfx",
- "//ui/gfx/geometry",
]
data_deps = [
diff --git a/ui/gl/gl_image.h b/ui/gl/gl_image.h
index aba2651..a236699 100644
--- a/ui/gl/gl_image.h
+++ b/ui/gl/gl_image.h
@@ -5,8 +5,6 @@
#ifndef UI_GL_GL_IMAGE_H_
#define UI_GL_GL_IMAGE_H_
-#include <string>
-
#include "base/memory/ref_counted.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/rect.h"
@@ -24,8 +22,8 @@ class ProcessMemoryDump;
namespace gfx {
-// Encapsulates an image that can be bound and/or copied to a texture, hiding
-// platform specific management.
+// Encapsulates an image that can be bound to a texture, hiding platform
+// specific management.
class GL_EXPORT GLImage : public base::RefCounted<GLImage> {
public:
GLImage() {}
@@ -34,32 +32,36 @@ class GL_EXPORT GLImage : public base::RefCounted<GLImage> {
virtual void Destroy(bool have_context) = 0;
// Get the size of the image.
- virtual Size GetSize() = 0;
+ virtual gfx::Size GetSize() = 0;
// Get the internal format of the image.
virtual unsigned GetInternalFormat() = 0;
- // Bind image to texture currently bound to |target|. Returns true on success.
- // It is valid for an implementation to always return false.
+ // Bind image to texture currently bound to |target|.
virtual bool BindTexImage(unsigned target) = 0;
// Release image from texture currently bound to |target|.
virtual void ReleaseTexImage(unsigned target) = 0;
- // Define texture currently bound to |target| by copying image into it.
- // Returns true on success. It is valid for an implementation to always
- // return false.
- virtual bool CopyTexImage(unsigned target) = 0;
-
// Copy |rect| of image to |offset| in texture currently bound to |target|.
- // Returns true on success. It is valid for an implementation to always
- // return false.
virtual bool CopyTexSubImage(unsigned target,
const Point& offset,
const Rect& rect) = 0;
+ // Called before the texture is used for drawing.
+ virtual void WillUseTexImage() = 0;
+
+ // Called after the texture has been used for drawing.
+ virtual void DidUseTexImage() = 0;
+
+ // Called before the texture image data will be modified.
+ virtual void WillModifyTexImage() = 0;
+
+ // Called after the texture image data has been modified.
+ virtual void DidModifyTexImage() = 0;
+
// Schedule image as an overlay plane to be shown at swap time for |widget|.
- virtual bool ScheduleOverlayPlane(AcceleratedWidget widget,
+ virtual bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
int z_order,
OverlayTransform transform,
const Rect& bounds_rect,
diff --git a/ui/gl/gl_image_egl.cc b/ui/gl/gl_image_egl.cc
index 6f72c4f..0ebd7cc 100644
--- a/ui/gl/gl_image_egl.cc
+++ b/ui/gl/gl_image_egl.cc
@@ -9,8 +9,9 @@
namespace gfx {
-GLImageEGL::GLImageEGL(const Size& size)
- : egl_image_(EGL_NO_IMAGE_KHR), size_(size) {}
+GLImageEGL::GLImageEGL(const gfx::Size& size)
+ : egl_image_(EGL_NO_IMAGE_KHR), size_(size) {
+}
GLImageEGL::~GLImageEGL() {
DCHECK(thread_checker_.CalledOnValidThread());
@@ -48,9 +49,7 @@ void GLImageEGL::Destroy(bool have_context) {
}
}
-Size GLImageEGL::GetSize() {
- return size_;
-}
+gfx::Size GLImageEGL::GetSize() { return size_; }
unsigned GLImageEGL::GetInternalFormat() { return GL_RGBA; }
@@ -62,17 +61,13 @@ bool GLImageEGL::BindTexImage(unsigned target) {
return true;
}
-bool GLImageEGL::CopyTexImage(unsigned target) {
- return false;
-}
-
bool GLImageEGL::CopyTexSubImage(unsigned target,
const Point& offset,
const Rect& rect) {
return false;
}
-bool GLImageEGL::ScheduleOverlayPlane(AcceleratedWidget widget,
+bool GLImageEGL::ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
int z_order,
OverlayTransform transform,
const Rect& bounds_rect,
diff --git a/ui/gl/gl_image_egl.h b/ui/gl/gl_image_egl.h
index 4110fd0d..14cc40b 100644
--- a/ui/gl/gl_image_egl.h
+++ b/ui/gl/gl_image_egl.h
@@ -13,21 +13,24 @@ namespace gfx {
class GL_EXPORT GLImageEGL : public GLImage {
public:
- explicit GLImageEGL(const Size& size);
+ explicit GLImageEGL(const gfx::Size& size);
bool Initialize(EGLenum target, EGLClientBuffer buffer, const EGLint* attrs);
// Overridden from GLImage:
void Destroy(bool have_context) override;
- Size GetSize() override;
+ gfx::Size GetSize() override;
unsigned GetInternalFormat() override;
bool BindTexImage(unsigned target) override;
void ReleaseTexImage(unsigned target) override {}
- bool CopyTexImage(unsigned target) override;
bool CopyTexSubImage(unsigned target,
const Point& offset,
const Rect& rect) override;
- bool ScheduleOverlayPlane(AcceleratedWidget widget,
+ void WillUseTexImage() override {}
+ void DidUseTexImage() override {}
+ void WillModifyTexImage() override {}
+ void DidModifyTexImage() override {}
+ bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
int z_order,
OverlayTransform transform,
const Rect& bounds_rect,
@@ -37,7 +40,7 @@ class GL_EXPORT GLImageEGL : public GLImage {
~GLImageEGL() override;
EGLImageKHR egl_image_;
- const Size size_;
+ const gfx::Size size_;
base::ThreadChecker thread_checker_;
private:
diff --git a/ui/gl/gl_image_glx.cc b/ui/gl/gl_image_glx.cc
index f2eddf9..496cf44 100644
--- a/ui/gl/gl_image_glx.cc
+++ b/ui/gl/gl_image_glx.cc
@@ -13,6 +13,7 @@ extern "C" {
#include "ui/gl/gl_surface_glx.h"
namespace gfx {
+
namespace {
bool ValidFormat(unsigned internalformat) {
@@ -61,7 +62,7 @@ unsigned PixmapDepth(unsigned internalformat) {
}
}
-bool ActualPixmapGeometry(XID pixmap, Size* size, unsigned* depth) {
+bool ActualPixmapGeometry(XID pixmap, gfx::Size* size, unsigned* depth) {
XID root_return;
int x_return;
int y_return;
@@ -69,13 +70,19 @@ bool ActualPixmapGeometry(XID pixmap, Size* size, unsigned* depth) {
unsigned height_return;
unsigned border_width_return;
unsigned depth_return;
- if (!XGetGeometry(GetXDisplay(), pixmap, &root_return, &x_return, &y_return,
- &width_return, &height_return, &border_width_return,
+ if (!XGetGeometry(gfx::GetXDisplay(),
+ pixmap,
+ &root_return,
+ &x_return,
+ &y_return,
+ &width_return,
+ &height_return,
+ &border_width_return,
&depth_return))
return false;
if (size)
- *size = Size(width_return, height_return);
+ *size = gfx::Size(width_return, height_return);
if (depth)
*depth = depth_return;
return true;
@@ -89,18 +96,19 @@ unsigned ActualPixmapDepth(XID pixmap) {
return depth;
}
-Size ActualPixmapSize(XID pixmap) {
- Size size;
+gfx::Size ActualPixmapSize(XID pixmap) {
+ gfx::Size size;
if (!ActualPixmapGeometry(pixmap, &size, NULL))
- return Size();
+ return gfx::Size();
return size;
}
-} // namespace
+} // namespace anonymous
-GLImageGLX::GLImageGLX(const Size& size, unsigned internalformat)
- : glx_pixmap_(0), size_(size), internalformat_(internalformat) {}
+GLImageGLX::GLImageGLX(const gfx::Size& size, unsigned internalformat)
+ : glx_pixmap_(0), size_(size), internalformat_(internalformat) {
+}
GLImageGLX::~GLImageGLX() {
DCHECK_EQ(0u, glx_pixmap_);
@@ -126,8 +134,8 @@ bool GLImageGLX::Initialize(XID pixmap) {
BindToTextureFormat(internalformat_), GL_TRUE,
0};
int num_elements = 0;
- XScopedPtr<GLXFBConfig> config(
- glXChooseFBConfig(GetXDisplay(), DefaultScreen(GetXDisplay()),
+ gfx::XScopedPtr<GLXFBConfig> config(
+ glXChooseFBConfig(gfx::GetXDisplay(), DefaultScreen(gfx::GetXDisplay()),
config_attribs, &num_elements));
if (!config.get()) {
DVLOG(0) << "glXChooseFBConfig failed.";
@@ -141,8 +149,8 @@ bool GLImageGLX::Initialize(XID pixmap) {
int pixmap_attribs[] = {GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT,
GLX_TEXTURE_FORMAT_EXT,
TextureFormat(internalformat_), 0};
- glx_pixmap_ =
- glXCreatePixmap(GetXDisplay(), *config.get(), pixmap, pixmap_attribs);
+ glx_pixmap_ = glXCreatePixmap(
+ gfx::GetXDisplay(), *config.get(), pixmap, pixmap_attribs);
if (!glx_pixmap_) {
DVLOG(0) << "glXCreatePixmap failed.";
return false;
@@ -153,14 +161,12 @@ bool GLImageGLX::Initialize(XID pixmap) {
void GLImageGLX::Destroy(bool have_context) {
if (glx_pixmap_) {
- glXDestroyGLXPixmap(GetXDisplay(), glx_pixmap_);
+ glXDestroyGLXPixmap(gfx::GetXDisplay(), glx_pixmap_);
glx_pixmap_ = 0;
}
}
-Size GLImageGLX::GetSize() {
- return size_;
-}
+gfx::Size GLImageGLX::GetSize() { return size_; }
unsigned GLImageGLX::GetInternalFormat() { return internalformat_; }
@@ -172,7 +178,7 @@ bool GLImageGLX::BindTexImage(unsigned target) {
if (target != GL_TEXTURE_2D)
return false;
- glXBindTexImageEXT(GetXDisplay(), glx_pixmap_, GLX_FRONT_LEFT_EXT, 0);
+ glXBindTexImageEXT(gfx::GetXDisplay(), glx_pixmap_, GLX_FRONT_LEFT_EXT, 0);
return true;
}
@@ -180,11 +186,7 @@ void GLImageGLX::ReleaseTexImage(unsigned target) {
DCHECK_NE(0u, glx_pixmap_);
DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D), target);
- glXReleaseTexImageEXT(GetXDisplay(), glx_pixmap_, GLX_FRONT_LEFT_EXT);
-}
-
-bool GLImageGLX::CopyTexImage(unsigned target) {
- return false;
+ glXReleaseTexImageEXT(gfx::GetXDisplay(), glx_pixmap_, GLX_FRONT_LEFT_EXT);
}
bool GLImageGLX::CopyTexSubImage(unsigned target,
@@ -193,7 +195,7 @@ bool GLImageGLX::CopyTexSubImage(unsigned target,
return false;
}
-bool GLImageGLX::ScheduleOverlayPlane(AcceleratedWidget widget,
+bool GLImageGLX::ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
int z_order,
OverlayTransform transform,
const Rect& bounds_rect,
diff --git a/ui/gl/gl_image_glx.h b/ui/gl/gl_image_glx.h
index e22512e..5de1d0d 100644
--- a/ui/gl/gl_image_glx.h
+++ b/ui/gl/gl_image_glx.h
@@ -14,21 +14,24 @@ namespace gfx {
class GL_EXPORT GLImageGLX : public GLImage {
public:
- GLImageGLX(const Size& size, unsigned internalformat);
+ GLImageGLX(const gfx::Size& size, unsigned internalformat);
bool Initialize(XID pixmap);
// Overridden from GLImage:
void Destroy(bool have_context) override;
- Size GetSize() override;
+ gfx::Size GetSize() override;
unsigned GetInternalFormat() override;
bool BindTexImage(unsigned target) override;
void ReleaseTexImage(unsigned target) override;
- bool CopyTexImage(unsigned target) override;
bool CopyTexSubImage(unsigned target,
const Point& offset,
const Rect& rect) override;
- bool ScheduleOverlayPlane(AcceleratedWidget widget,
+ void WillUseTexImage() override {}
+ void DidUseTexImage() override {}
+ void WillModifyTexImage() override {}
+ void DidModifyTexImage() override {}
+ bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
int z_order,
OverlayTransform transform,
const Rect& bounds_rect,
@@ -42,7 +45,7 @@ class GL_EXPORT GLImageGLX : public GLImage {
private:
XID glx_pixmap_;
- const Size size_;
+ const gfx::Size size_;
unsigned internalformat_;
DISALLOW_COPY_AND_ASSIGN(GLImageGLX);
diff --git a/ui/gl/gl_image_io_surface.h b/ui/gl/gl_image_io_surface.h
index 45bd3ac..56b4478 100644
--- a/ui/gl/gl_image_io_surface.h
+++ b/ui/gl/gl_image_io_surface.h
@@ -9,8 +9,7 @@
#include "base/mac/scoped_cftyperef.h"
#include "base/threading/thread_checker.h"
-#include "ui/gfx/buffer_types.h"
-#include "ui/gfx/generic_shared_memory_id.h"
+#include "ui/gfx/gpu_memory_buffer.h"
#include "ui/gl/gl_image.h"
#if defined(__OBJC__)
@@ -23,23 +22,26 @@ namespace gfx {
class GL_EXPORT GLImageIOSurface : public GLImage {
public:
- GLImageIOSurface(const Size& size, unsigned internalformat);
+ GLImageIOSurface(const gfx::Size& size, unsigned internalformat);
bool Initialize(IOSurfaceRef io_surface,
- GenericSharedMemoryId io_surface_id,
+ gfx::GenericSharedMemoryId io_surface_id,
BufferFormat format);
// Overridden from GLImage:
void Destroy(bool have_context) override;
- Size GetSize() override;
+ gfx::Size GetSize() override;
unsigned GetInternalFormat() override;
bool BindTexImage(unsigned target) override;
void ReleaseTexImage(unsigned target) override {}
- bool CopyTexImage(unsigned target) override;
bool CopyTexSubImage(unsigned target,
const Point& offset,
const Rect& rect) override;
- bool ScheduleOverlayPlane(AcceleratedWidget widget,
+ void WillUseTexImage() override {}
+ void DidUseTexImage() override {}
+ void WillModifyTexImage() override {}
+ void DidModifyTexImage() override {}
+ bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
int z_order,
OverlayTransform transform,
const Rect& bounds_rect,
@@ -50,17 +52,18 @@ class GL_EXPORT GLImageIOSurface : public GLImage {
base::ScopedCFTypeRef<IOSurfaceRef> io_surface();
- static void SetLayerForWidget(AcceleratedWidget widget, CALayer* layer);
+ static void SetLayerForWidget(gfx::AcceleratedWidget widget,
+ CALayer* layer);
protected:
~GLImageIOSurface() override;
private:
- const Size size_;
+ const gfx::Size size_;
const unsigned internalformat_;
BufferFormat format_;
base::ScopedCFTypeRef<IOSurfaceRef> io_surface_;
- GenericSharedMemoryId io_surface_id_;
+ gfx::GenericSharedMemoryId io_surface_id_;
base::ThreadChecker thread_checker_;
DISALLOW_COPY_AND_ASSIGN(GLImageIOSurface);
diff --git a/ui/gl/gl_image_io_surface.mm b/ui/gl/gl_image_io_surface.mm
index 4294298..3f4964e 100644
--- a/ui/gl/gl_image_io_surface.mm
+++ b/ui/gl/gl_image_io_surface.mm
@@ -8,9 +8,6 @@
#include "base/lazy_instance.h"
#include "base/mac/foundation_util.h"
-#include "base/trace_event/memory_allocator_dump.h"
-#include "base/trace_event/memory_dump_manager.h"
-#include "base/trace_event/process_memory_dump.h"
#include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_context.h"
@@ -21,7 +18,7 @@
namespace gfx {
namespace {
-using WidgetToLayerMap = std::map<AcceleratedWidget, CALayer*>;
+typedef std::map<gfx::AcceleratedWidget,CALayer*> WidgetToLayerMap;
base::LazyInstance<WidgetToLayerMap> g_widget_to_layer_map;
bool ValidInternalFormat(unsigned internalformat) {
@@ -141,7 +138,8 @@ GLenum DataType(BufferFormat format) {
} // namespace
-GLImageIOSurface::GLImageIOSurface(const Size& size, unsigned internalformat)
+GLImageIOSurface::GLImageIOSurface(const gfx::Size& size,
+ unsigned internalformat)
: size_(size),
internalformat_(internalformat),
format_(BufferFormat::RGBA_8888) {}
@@ -152,7 +150,7 @@ GLImageIOSurface::~GLImageIOSurface() {
}
bool GLImageIOSurface::Initialize(IOSurfaceRef io_surface,
- GenericSharedMemoryId io_surface_id,
+ gfx::GenericSharedMemoryId io_surface_id,
BufferFormat format) {
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(!io_surface_);
@@ -178,9 +176,7 @@ void GLImageIOSurface::Destroy(bool have_context) {
io_surface_.reset();
}
-Size GLImageIOSurface::GetSize() {
- return size_;
-}
+gfx::Size GLImageIOSurface::GetSize() { return size_; }
unsigned GLImageIOSurface::GetInternalFormat() { return internalformat_; }
@@ -209,17 +205,13 @@ bool GLImageIOSurface::BindTexImage(unsigned target) {
return true;
}
-bool GLImageIOSurface::CopyTexImage(unsigned target) {
- return false;
-}
-
bool GLImageIOSurface::CopyTexSubImage(unsigned target,
const Point& offset,
const Rect& rect) {
return false;
}
-bool GLImageIOSurface::ScheduleOverlayPlane(AcceleratedWidget widget,
+bool GLImageIOSurface::ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
int z_order,
OverlayTransform transform,
const Rect& bounds_rect,
@@ -241,8 +233,8 @@ void GLImageIOSurface::OnMemoryDump(base::trace_event::ProcessMemoryDump* pmd,
base::trace_event::MemoryAllocatorDump::kUnitsBytes,
static_cast<uint64_t>(size_bytes));
- auto guid =
- GetGenericSharedMemoryGUIDForTracing(process_tracing_id, io_surface_id_);
+ auto guid = gfx::GetGenericSharedMemoryGUIDForTracing(process_tracing_id,
+ io_surface_id_);
pmd->CreateSharedGlobalAllocatorDump(guid);
pmd->AddOwnershipEdge(dump->guid(), guid);
}
@@ -252,8 +244,8 @@ base::ScopedCFTypeRef<IOSurfaceRef> GLImageIOSurface::io_surface() {
}
// static
-void GLImageIOSurface::SetLayerForWidget(AcceleratedWidget widget,
- CALayer* layer) {
+void GLImageIOSurface::SetLayerForWidget(
+ gfx::AcceleratedWidget widget, CALayer* layer) {
if (layer)
g_widget_to_layer_map.Pointer()->insert(std::make_pair(widget, layer));
else
diff --git a/ui/gl/gl_image_memory.cc b/ui/gl/gl_image_memory.cc
index 045c50c..c91ad56 100644
--- a/ui/gl/gl_image_memory.cc
+++ b/ui/gl/gl_image_memory.cc
@@ -7,6 +7,12 @@
#include "base/logging.h"
#include "base/trace_event/trace_event.h"
#include "ui/gl/gl_bindings.h"
+#include "ui/gl/scoped_binders.h"
+
+#if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \
+ defined(USE_OZONE)
+#include "ui/gl/gl_surface_egl.h"
+#endif
namespace gfx {
namespace {
@@ -146,11 +152,26 @@ GLsizei SizeInBytes(const Size& size, BufferFormat format) {
GLImageMemory::GLImageMemory(const Size& size, unsigned internalformat)
: size_(size),
internalformat_(internalformat),
- memory_(nullptr),
- format_(BufferFormat::RGBA_8888) {}
+ memory_(NULL),
+ format_(BufferFormat::RGBA_8888),
+ in_use_(false),
+ target_(0),
+ need_do_bind_tex_image_(false)
+#if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \
+ defined(USE_OZONE)
+ ,
+ egl_texture_id_(0u),
+ egl_image_(EGL_NO_IMAGE_KHR)
+#endif
+{
+}
GLImageMemory::~GLImageMemory() {
- DCHECK(!memory_);
+#if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \
+ defined(USE_OZONE)
+ DCHECK_EQ(EGL_NO_IMAGE_KHR, egl_image_);
+ DCHECK_EQ(0u, egl_texture_id_);
+#endif
}
// static
@@ -222,7 +243,20 @@ bool GLImageMemory::Initialize(const unsigned char* memory,
}
void GLImageMemory::Destroy(bool have_context) {
- memory_ = nullptr;
+#if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \
+ defined(USE_OZONE)
+ if (egl_image_ != EGL_NO_IMAGE_KHR) {
+ eglDestroyImageKHR(GLSurfaceEGL::GetHardwareDisplay(), egl_image_);
+ egl_image_ = EGL_NO_IMAGE_KHR;
+ }
+
+ if (egl_texture_id_) {
+ if (have_context)
+ glDeleteTextures(1, &egl_texture_id_);
+ egl_texture_id_ = 0u;
+ }
+#endif
+ memory_ = NULL;
}
Size GLImageMemory::GetSize() {
@@ -234,27 +268,19 @@ unsigned GLImageMemory::GetInternalFormat() {
}
bool GLImageMemory::BindTexImage(unsigned target) {
- return false;
-}
-
-bool GLImageMemory::CopyTexImage(unsigned target) {
- TRACE_EVENT2("gpu", "GLImageMemory::CopyTexImage", "width", size_.width(),
- "height", size_.height());
-
- // GL_TEXTURE_EXTERNAL_OES is not a supported target.
- if (target == GL_TEXTURE_EXTERNAL_OES)
+ if (target_ && target_ != target) {
+ LOG(ERROR) << "GLImage can only be bound to one target";
return false;
+ }
+ target_ = target;
- if (IsCompressedFormat(format_)) {
- glCompressedTexImage2D(target, 0, TextureFormat(format_), size_.width(),
- size_.height(), 0, SizeInBytes(size_, format_),
- memory_);
- } else {
- glTexImage2D(target, 0, TextureFormat(format_), size_.width(),
- size_.height(), 0, DataFormat(format_), DataType(format_),
- memory_);
+ // Defer DoBindTexImage if not currently in use.
+ if (!in_use_) {
+ need_do_bind_tex_image_ = true;
+ return true;
}
+ DoBindTexImage(target);
return true;
}
@@ -264,7 +290,7 @@ bool GLImageMemory::CopyTexSubImage(unsigned target,
TRACE_EVENT2("gpu", "GLImageMemory::CopyTexSubImage", "width", rect.width(),
"height", rect.height());
- // GL_TEXTURE_EXTERNAL_OES is not a supported target.
+ // GL_TEXTURE_EXTERNAL_OES is not a supported CopyTexSubImage target.
if (target == GL_TEXTURE_EXTERNAL_OES)
return false;
@@ -282,18 +308,36 @@ bool GLImageMemory::CopyTexSubImage(unsigned target,
DCHECK(memory_);
const unsigned char* data = memory_ + rect.y() * stride_in_bytes;
if (IsCompressedFormat(format_)) {
- glCompressedTexSubImage2D(target, 0, offset.x(), offset.y(), rect.width(),
+ glCompressedTexSubImage2D(target,
+ 0, // level
+ offset.x(), offset.y(), rect.width(),
rect.height(), DataFormat(format_),
SizeInBytes(rect.size(), format_), data);
} else {
- glTexSubImage2D(target, 0, offset.x(), offset.y(), rect.width(),
- rect.height(), DataFormat(format_), DataType(format_),
- data);
+ glTexSubImage2D(target, 0, // level
+ offset.x(), offset.y(), rect.width(), rect.height(),
+ DataFormat(format_), DataType(format_), data);
}
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(AcceleratedWidget widget,
int z_order,
OverlayTransform transform,
@@ -302,4 +346,132 @@ bool GLImageMemory::ScheduleOverlayPlane(AcceleratedWidget widget,
return false;
}
+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) || \
+ defined(USE_OZONE)
+ if (target == GL_TEXTURE_EXTERNAL_OES) {
+ if (egl_image_ == EGL_NO_IMAGE_KHR) {
+ DCHECK_EQ(0u, egl_texture_id_);
+ glGenTextures(1, &egl_texture_id_);
+
+ {
+ ScopedTextureBinder texture_binder(GL_TEXTURE_2D, egl_texture_id_);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ if (IsCompressedFormat(format_)) {
+ glCompressedTexImage2D(GL_TEXTURE_2D,
+ 0, // mip level
+ TextureFormat(format_), size_.width(),
+ size_.height(),
+ 0, // border
+ SizeInBytes(size_, format_), memory_);
+ } else {
+ glTexImage2D(GL_TEXTURE_2D,
+ 0, // mip level
+ TextureFormat(format_),
+ size_.width(),
+ size_.height(),
+ 0, // border
+ DataFormat(format_),
+ DataType(format_),
+ memory_);
+ }
+ }
+
+ EGLint attrs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE};
+ // Need to pass current EGL rendering context to eglCreateImageKHR for
+ // target type EGL_GL_TEXTURE_2D_KHR.
+ egl_image_ =
+ eglCreateImageKHR(GLSurfaceEGL::GetHardwareDisplay(),
+ eglGetCurrentContext(),
+ EGL_GL_TEXTURE_2D_KHR,
+ reinterpret_cast<EGLClientBuffer>(egl_texture_id_),
+ attrs);
+ DCHECK_NE(EGL_NO_IMAGE_KHR, egl_image_)
+ << "Error creating EGLImage: " << eglGetError();
+ } else {
+ ScopedTextureBinder texture_binder(GL_TEXTURE_2D, egl_texture_id_);
+
+ if (IsCompressedFormat(format_)) {
+ glCompressedTexSubImage2D(GL_TEXTURE_2D,
+ 0, // mip level
+ 0, // x-offset
+ 0, // y-offset
+ size_.width(), size_.height(),
+ DataFormat(format_),
+ SizeInBytes(size_, format_), memory_);
+ } else {
+ glTexSubImage2D(GL_TEXTURE_2D,
+ 0, // mip level
+ 0, // x-offset
+ 0, // y-offset
+ size_.width(),
+ size_.height(),
+ DataFormat(format_),
+ DataType(format_),
+ memory_);
+ }
+ }
+
+ glEGLImageTargetTexture2DOES(target, egl_image_);
+ DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
+ return;
+ }
+#endif
+
+ DCHECK_NE(static_cast<GLenum>(GL_TEXTURE_EXTERNAL_OES), target);
+ if (IsCompressedFormat(format_)) {
+ glCompressedTexImage2D(target,
+ 0, // mip level
+ TextureFormat(format_), size_.width(),
+ size_.height(),
+ 0, // border
+ SizeInBytes(size_, format_), memory_);
+ } else {
+ glTexImage2D(target,
+ 0, // mip level
+ TextureFormat(format_),
+ size_.width(),
+ size_.height(),
+ 0, // border
+ DataFormat(format_),
+ DataType(format_),
+ memory_);
+ }
+}
+
+void GLImageMemory::OnMemoryDump(base::trace_event::ProcessMemoryDump* pmd,
+ uint64_t process_tracing_id,
+ const std::string& dump_name) {
+ // Note that the following calculation does not consider whether this GLImage
+ // has been un-bound from a texture. It also relies on this GLImage only ever
+ // being bound to a single texture. We could check these conditions more
+ // thoroughly, but at the cost of extra GL queries.
+ bool is_bound_to_texture = target_ && !need_do_bind_tex_image_;
+
+#if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \
+ defined(USE_OZONE)
+ is_bound_to_texture |= !!egl_texture_id_;
+#endif
+
+ size_t size_in_bytes = is_bound_to_texture ? SizeInBytes(size_, format_) : 0;
+
+ base::trace_event::MemoryAllocatorDump* dump =
+ pmd->CreateAllocatorDump(dump_name + "/texture_memory");
+ dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize,
+ base::trace_event::MemoryAllocatorDump::kUnitsBytes,
+ static_cast<uint64_t>(size_in_bytes));
+
+ // No need for a global shared edge here. This object in the GPU process is
+ // the sole owner of this texture id.
+}
+
} // namespace gfx
diff --git a/ui/gl/gl_image_memory.h b/ui/gl/gl_image_memory.h
index 4f1fe04..10b1a3b 100644
--- a/ui/gl/gl_image_memory.h
+++ b/ui/gl/gl_image_memory.h
@@ -7,8 +7,14 @@
#include "ui/gl/gl_image.h"
+#if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \
+ defined(USE_OZONE)
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#endif
+
#include "base/numerics/safe_math.h"
-#include "ui/gfx/buffer_types.h"
+#include "ui/gfx/gpu_memory_buffer.h"
namespace gfx {
@@ -28,26 +34,45 @@ class GL_EXPORT GLImageMemory : public GLImage {
unsigned GetInternalFormat() override;
bool BindTexImage(unsigned target) override;
void ReleaseTexImage(unsigned target) override {}
- bool CopyTexImage(unsigned target) override;
bool CopyTexSubImage(unsigned target,
const Point& offset,
const Rect& rect) override;
+ void WillUseTexImage() override;
+ void DidUseTexImage() override;
+ void WillModifyTexImage() override {}
+ void DidModifyTexImage() override {}
bool ScheduleOverlayPlane(AcceleratedWidget widget,
int z_order,
OverlayTransform transform,
const Rect& bounds_rect,
const RectF& crop_rect) override;
+ // Only dumps the GLTexture portion of the memory usage. Subclasses are
+ // responsible for dumping the CPU-side memory.
+ void OnMemoryDump(base::trace_event::ProcessMemoryDump* pmd,
+ uint64_t process_tracing_id,
+ const std::string& dump_name) override;
+
protected:
~GLImageMemory() override;
BufferFormat format() const { return format_; }
private:
+ void DoBindTexImage(unsigned target);
+
const Size size_;
const unsigned internalformat_;
const unsigned char* memory_;
BufferFormat format_;
+ 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_;
+ EGLImageKHR egl_image_;
+#endif
DISALLOW_COPY_AND_ASSIGN(GLImageMemory);
};
diff --git a/ui/gl/gl_image_ozone_native_pixmap.cc b/ui/gl/gl_image_ozone_native_pixmap.cc
index e0d0e37..3e0cfb5 100644
--- a/ui/gl/gl_image_ozone_native_pixmap.cc
+++ b/ui/gl/gl_image_ozone_native_pixmap.cc
@@ -26,7 +26,7 @@ bool ValidInternalFormat(unsigned internalformat) {
}
}
-bool ValidFormat(BufferFormat format) {
+bool ValidFormat(gfx::BufferFormat format) {
switch (format) {
case BufferFormat::RGBA_8888:
case BufferFormat::BGRA_8888:
@@ -49,7 +49,7 @@ bool ValidFormat(BufferFormat format) {
return false;
}
-EGLint FourCC(BufferFormat format) {
+EGLint FourCC(gfx::BufferFormat format) {
switch (format) {
case BufferFormat::RGBA_8888:
return DRM_FORMAT_ABGR8888;
@@ -87,12 +87,12 @@ GLImageOzoneNativePixmap::~GLImageOzoneNativePixmap() {
bool GLImageOzoneNativePixmap::Initialize(ui::NativePixmap* pixmap,
BufferFormat format) {
DCHECK(!pixmap_);
+
+ bool result = true;
if (pixmap->GetEGLClientBuffer()) {
EGLint attrs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE};
- if (!GLImageEGL::Initialize(EGL_NATIVE_PIXMAP_KHR,
- pixmap->GetEGLClientBuffer(), attrs)) {
- return false;
- }
+ result = GLImageEGL::Initialize(EGL_NATIVE_PIXMAP_KHR,
+ pixmap->GetEGLClientBuffer(), attrs);
} else if (pixmap->GetDmaBufFd() >= 0) {
if (!ValidInternalFormat(internalformat_)) {
LOG(ERROR) << "Invalid internalformat: " << internalformat_;
@@ -119,14 +119,13 @@ bool GLImageOzoneNativePixmap::Initialize(ui::NativePixmap* pixmap,
EGL_DMA_BUF_PLANE0_PITCH_EXT,
pixmap->GetDmaBufPitch(),
EGL_NONE};
- if (!GLImageEGL::Initialize(EGL_LINUX_DMA_BUF_EXT,
- static_cast<EGLClientBuffer>(nullptr), attrs)) {
- return false;
- }
+ result = GLImageEGL::Initialize(
+ EGL_LINUX_DMA_BUF_EXT, static_cast<EGLClientBuffer>(nullptr), attrs);
}
- pixmap_ = pixmap;
- return true;
+ if (result)
+ pixmap_ = pixmap;
+ return result;
}
unsigned GLImageOzoneNativePixmap::GetInternalFormat() {
diff --git a/ui/gl/gl_image_ozone_native_pixmap.h b/ui/gl/gl_image_ozone_native_pixmap.h
index 6505299..e164f39 100644
--- a/ui/gl/gl_image_ozone_native_pixmap.h
+++ b/ui/gl/gl_image_ozone_native_pixmap.h
@@ -5,7 +5,7 @@
#ifndef UI_GL_GL_IMAGE_OZONE_NATIVE_PIXMAP_H_
#define UI_GL_GL_IMAGE_OZONE_NATIVE_PIXMAP_H_
-#include "ui/gfx/buffer_types.h"
+#include "ui/gfx/gpu_memory_buffer.h"
#include "ui/gl/gl_image_egl.h"
#include "ui/ozone/public/native_pixmap.h"
diff --git a/ui/gl/gl_image_ref_counted_memory.cc b/ui/gl/gl_image_ref_counted_memory.cc
index 6533568..7aadd24 100644
--- a/ui/gl/gl_image_ref_counted_memory.cc
+++ b/ui/gl/gl_image_ref_counted_memory.cc
@@ -6,15 +6,13 @@
#include "base/logging.h"
#include "base/memory/ref_counted_memory.h"
-#include "base/trace_event/memory_allocator_dump.h"
-#include "base/trace_event/memory_dump_manager.h"
-#include "base/trace_event/process_memory_dump.h"
namespace gfx {
-GLImageRefCountedMemory::GLImageRefCountedMemory(const Size& size,
+GLImageRefCountedMemory::GLImageRefCountedMemory(const gfx::Size& size,
unsigned internalformat)
- : GLImageMemory(size, internalformat) {}
+ : GLImageMemory(size, internalformat) {
+}
GLImageRefCountedMemory::~GLImageRefCountedMemory() {
DCHECK(!ref_counted_memory_.get());
@@ -22,7 +20,7 @@ GLImageRefCountedMemory::~GLImageRefCountedMemory() {
bool GLImageRefCountedMemory::Initialize(
base::RefCountedMemory* ref_counted_memory,
- BufferFormat format) {
+ gfx::BufferFormat format) {
if (!GLImageMemory::Initialize(ref_counted_memory->front(), format))
return false;
@@ -33,7 +31,7 @@ bool GLImageRefCountedMemory::Initialize(
void GLImageRefCountedMemory::Destroy(bool have_context) {
GLImageMemory::Destroy(have_context);
- ref_counted_memory_ = nullptr;
+ ref_counted_memory_ = NULL;
}
void GLImageRefCountedMemory::OnMemoryDump(
@@ -54,6 +52,9 @@ void GLImageRefCountedMemory::OnMemoryDump(
pmd->AddSuballocation(dump->guid(),
base::trace_event::MemoryDumpManager::GetInstance()
->system_allocator_pool_name());
+
+ // Also dump the base class's texture memory.
+ GLImageMemory::OnMemoryDump(pmd, process_tracing_id, dump_name);
}
} // namespace gfx
diff --git a/ui/gl/gl_image_ref_counted_memory.h b/ui/gl/gl_image_ref_counted_memory.h
index f68acc5..db07954 100644
--- a/ui/gl/gl_image_ref_counted_memory.h
+++ b/ui/gl/gl_image_ref_counted_memory.h
@@ -16,10 +16,10 @@ namespace gfx {
class GL_EXPORT GLImageRefCountedMemory : public GLImageMemory {
public:
- GLImageRefCountedMemory(const Size& size, unsigned internalformat);
+ GLImageRefCountedMemory(const gfx::Size& size, unsigned internalformat);
bool Initialize(base::RefCountedMemory* ref_counted_memory,
- BufferFormat format);
+ gfx::BufferFormat format);
// Overridden from GLImage:
void Destroy(bool have_context) override;
diff --git a/ui/gl/gl_image_ref_counted_memory_unittest.cc b/ui/gl/gl_image_ref_counted_memory_unittest.cc
index c3d77e2..1edccf2 100644
--- a/ui/gl/gl_image_ref_counted_memory_unittest.cc
+++ b/ui/gl/gl_image_ref_counted_memory_unittest.cc
@@ -37,9 +37,5 @@ INSTANTIATE_TYPED_TEST_CASE_P(GLImageRefCountedMemory,
GLImageTest,
GLImageRefCountedMemoryTestDelegate);
-INSTANTIATE_TYPED_TEST_CASE_P(GLImageRefCountedMemory,
- GLImageCopyTest,
- GLImageRefCountedMemoryTestDelegate);
-
} // namespace
} // namespace gfx
diff --git a/ui/gl/gl_image_shared_memory.cc b/ui/gl/gl_image_shared_memory.cc
index 6ca7905..16ec6cb 100644
--- a/ui/gl/gl_image_shared_memory.cc
+++ b/ui/gl/gl_image_shared_memory.cc
@@ -5,18 +5,16 @@
#include "ui/gl/gl_image_shared_memory.h"
#include "base/logging.h"
-#include "base/memory/shared_memory.h"
#include "base/numerics/safe_math.h"
#include "base/process/process_handle.h"
-#include "base/trace_event/memory_allocator_dump.h"
-#include "base/trace_event/memory_dump_manager.h"
-#include "base/trace_event/process_memory_dump.h"
namespace gfx {
namespace {
// Returns true if the size is valid and false otherwise.
-bool SizeInBytes(const Size& size, BufferFormat format, size_t* size_in_bytes) {
+bool SizeInBytes(const gfx::Size& size,
+ gfx::BufferFormat format,
+ size_t* size_in_bytes) {
if (size.IsEmpty())
return false;
@@ -33,17 +31,19 @@ bool SizeInBytes(const Size& size, BufferFormat format, size_t* size_in_bytes) {
} // namespace
-GLImageSharedMemory::GLImageSharedMemory(const Size& size,
+GLImageSharedMemory::GLImageSharedMemory(const gfx::Size& size,
unsigned internalformat)
- : GLImageMemory(size, internalformat) {}
+ : GLImageMemory(size, internalformat) {
+}
GLImageSharedMemory::~GLImageSharedMemory() {
DCHECK(!shared_memory_);
}
-bool GLImageSharedMemory::Initialize(const base::SharedMemoryHandle& handle,
- GenericSharedMemoryId shared_memory_id,
- BufferFormat format) {
+bool GLImageSharedMemory::Initialize(
+ const base::SharedMemoryHandle& handle,
+ gfx::GenericSharedMemoryId shared_memory_id,
+ gfx::BufferFormat format) {
size_t size_in_bytes;
if (!SizeInBytes(GetSize(), format, &size_in_bytes))
return false;
@@ -98,15 +98,18 @@ void GLImageSharedMemory::OnMemoryDump(
// Dump under "/shared_memory", as the base class may also dump to
// "/texture_memory".
base::trace_event::MemoryAllocatorDump* dump =
- pmd->CreateAllocatorDump(dump_name + "/shared_memory");
+ pmd->CreateAllocatorDump(dump_name + "/private_memory");
dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize,
base::trace_event::MemoryAllocatorDump::kUnitsBytes,
static_cast<uint64_t>(size_in_bytes));
- auto guid = GetGenericSharedMemoryGUIDForTracing(process_tracing_id,
- shared_memory_id_);
+ auto guid = gfx::GetGenericSharedMemoryGUIDForTracing(process_tracing_id,
+ shared_memory_id_);
pmd->CreateSharedGlobalAllocatorDump(guid);
pmd->AddOwnershipEdge(dump->guid(), guid);
+
+ // Also dump the base class's texture memory.
+ GLImageMemory::OnMemoryDump(pmd, process_tracing_id, dump_name);
}
} // namespace gfx
diff --git a/ui/gl/gl_image_shared_memory.h b/ui/gl/gl_image_shared_memory.h
index 2e6374b5..622eb3d 100644
--- a/ui/gl/gl_image_shared_memory.h
+++ b/ui/gl/gl_image_shared_memory.h
@@ -7,21 +7,16 @@
#include "base/memory/scoped_ptr.h"
#include "base/memory/shared_memory_handle.h"
-#include "ui/gfx/generic_shared_memory_id.h"
#include "ui/gl/gl_image_memory.h"
-namespace base {
-class SharedMemory;
-}
-
namespace gfx {
class GL_EXPORT GLImageSharedMemory : public GLImageMemory {
public:
- GLImageSharedMemory(const Size& size, unsigned internalformat);
+ GLImageSharedMemory(const gfx::Size& size, unsigned internalformat);
bool Initialize(const base::SharedMemoryHandle& handle,
- GenericSharedMemoryId shared_memory_id,
+ gfx::GenericSharedMemoryId shared_memory_id,
BufferFormat format);
// Overridden from GLImage:
diff --git a/ui/gl/gl_image_shared_memory_unittest.cc b/ui/gl/gl_image_shared_memory_unittest.cc
index 9c280f9..44c8e97 100644
--- a/ui/gl/gl_image_shared_memory_unittest.cc
+++ b/ui/gl/gl_image_shared_memory_unittest.cc
@@ -39,9 +39,5 @@ INSTANTIATE_TYPED_TEST_CASE_P(GLImageSharedMemory,
GLImageTest,
GLImageSharedMemoryTestDelegate);
-INSTANTIATE_TYPED_TEST_CASE_P(GLImageSharedMemory,
- GLImageCopyTest,
- GLImageSharedMemoryTestDelegate);
-
} // namespace
} // namespace gfx
diff --git a/ui/gl/gl_image_stub.cc b/ui/gl/gl_image_stub.cc
index 803a05f..afbf6e0 100644
--- a/ui/gl/gl_image_stub.cc
+++ b/ui/gl/gl_image_stub.cc
@@ -12,25 +12,19 @@ GLImageStub::GLImageStub() {}
GLImageStub::~GLImageStub() {}
-Size GLImageStub::GetSize() {
- return Size(1, 1);
-}
+gfx::Size GLImageStub::GetSize() { return gfx::Size(1, 1); }
unsigned GLImageStub::GetInternalFormat() { return GL_RGBA; }
bool GLImageStub::BindTexImage(unsigned target) { return true; }
-bool GLImageStub::CopyTexImage(unsigned target) {
- return true;
-}
-
bool GLImageStub::CopyTexSubImage(unsigned target,
const Point& offset,
const Rect& rect) {
return true;
}
-bool GLImageStub::ScheduleOverlayPlane(AcceleratedWidget widget,
+bool GLImageStub::ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
int z_order,
OverlayTransform transform,
const Rect& bounds_rect,
diff --git a/ui/gl/gl_image_stub.h b/ui/gl/gl_image_stub.h
index c95fda9..be31bff 100644
--- a/ui/gl/gl_image_stub.h
+++ b/ui/gl/gl_image_stub.h
@@ -16,15 +16,18 @@ class GL_EXPORT GLImageStub : public GLImage {
// Overridden from GLImage:
void Destroy(bool have_context) override {}
- Size GetSize() override;
+ gfx::Size GetSize() override;
unsigned GetInternalFormat() override;
bool BindTexImage(unsigned target) override;
void ReleaseTexImage(unsigned target) override {}
- bool CopyTexImage(unsigned target) override;
bool CopyTexSubImage(unsigned target,
const Point& offset,
const Rect& rect) override;
- bool ScheduleOverlayPlane(AcceleratedWidget widget,
+ void WillUseTexImage() override {}
+ void DidUseTexImage() override {}
+ void WillModifyTexImage() override {}
+ void DidModifyTexImage() override {}
+ bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
int z_order,
OverlayTransform transform,
const Rect& bounds_rect,
diff --git a/ui/gl/gl_image_surface_texture.cc b/ui/gl/gl_image_surface_texture.cc
index 6ad3667..910551d 100644
--- a/ui/gl/gl_image_surface_texture.cc
+++ b/ui/gl/gl_image_surface_texture.cc
@@ -9,8 +9,9 @@
namespace gfx {
-GLImageSurfaceTexture::GLImageSurfaceTexture(const Size& size)
- : size_(size), texture_id_(0) {}
+GLImageSurfaceTexture::GLImageSurfaceTexture(const gfx::Size& size)
+ : size_(size), texture_id_(0) {
+}
GLImageSurfaceTexture::~GLImageSurfaceTexture() {
DCHECK(thread_checker_.CalledOnValidThread());
@@ -31,9 +32,7 @@ void GLImageSurfaceTexture::Destroy(bool have_context) {
texture_id_ = 0;
}
-Size GLImageSurfaceTexture::GetSize() {
- return size_;
-}
+gfx::Size GLImageSurfaceTexture::GetSize() { return size_; }
unsigned GLImageSurfaceTexture::GetInternalFormat() { return GL_RGBA; }
@@ -79,17 +78,13 @@ bool GLImageSurfaceTexture::BindTexImage(unsigned target) {
return true;
}
-bool GLImageSurfaceTexture::CopyTexImage(unsigned target) {
- return false;
-}
-
bool GLImageSurfaceTexture::CopyTexSubImage(unsigned target,
const Point& offset,
const Rect& rect) {
return false;
}
-bool GLImageSurfaceTexture::ScheduleOverlayPlane(AcceleratedWidget widget,
+bool GLImageSurfaceTexture::ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
int z_order,
OverlayTransform transform,
const Rect& bounds_rect,
diff --git a/ui/gl/gl_image_surface_texture.h b/ui/gl/gl_image_surface_texture.h
index f18eaa2..d8c4abb 100644
--- a/ui/gl/gl_image_surface_texture.h
+++ b/ui/gl/gl_image_surface_texture.h
@@ -15,21 +15,24 @@ class SurfaceTexture;
class GL_EXPORT GLImageSurfaceTexture : public GLImage {
public:
- explicit GLImageSurfaceTexture(const Size& size);
+ explicit GLImageSurfaceTexture(const gfx::Size& size);
bool Initialize(SurfaceTexture* surface_texture);
// Overridden from GLImage:
void Destroy(bool have_context) override;
- Size GetSize() override;
+ gfx::Size GetSize() override;
unsigned GetInternalFormat() override;
bool BindTexImage(unsigned target) override;
void ReleaseTexImage(unsigned target) override {}
- bool CopyTexImage(unsigned target) override;
bool CopyTexSubImage(unsigned target,
const Point& offset,
const Rect& rect) override;
- bool ScheduleOverlayPlane(AcceleratedWidget widget,
+ void WillUseTexImage() override {}
+ void DidUseTexImage() override {}
+ void WillModifyTexImage() override {}
+ void DidModifyTexImage() override {}
+ bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
int z_order,
OverlayTransform transform,
const Rect& bounds_rect,
@@ -43,7 +46,7 @@ class GL_EXPORT GLImageSurfaceTexture : public GLImage {
private:
scoped_refptr<SurfaceTexture> surface_texture_;
- const Size size_;
+ const gfx::Size size_;
GLint texture_id_;
base::ThreadChecker thread_checker_;
diff --git a/ui/gl/gl_tests.gyp b/ui/gl/gl_tests.gyp
index eaf0df0..09821e7 100644
--- a/ui/gl/gl_tests.gyp
+++ b/ui/gl/gl_tests.gyp
@@ -28,7 +28,6 @@
'<(DEPTH)/testing/gtest.gyp:gtest',
'<(DEPTH)/third_party/mesa/mesa.gyp:osmesa',
'<(DEPTH)/ui/gfx/gfx.gyp:gfx',
- '<(DEPTH)/ui/gfx/gfx.gyp:gfx_geometry',
'<(DEPTH)/ui/gl/gl.gyp:gl',
'<(DEPTH)/ui/gl/gl.gyp:gl_test_support',
'<(DEPTH)/ui/gl/gl.gyp:gl_unittest_utils',
diff --git a/ui/gl/test/gl_image_test_template.h b/ui/gl/test/gl_image_test_template.h
index e7b685d..8533ce2 100644
--- a/ui/gl/test/gl_image_test_template.h
+++ b/ui/gl/test/gl_image_test_template.h
@@ -51,51 +51,9 @@ class GLImageTest : public testing::Test {
TYPED_TEST_CASE_P(GLImageTest);
-TYPED_TEST_P(GLImageTest, CreateAndDestroy) {
- const Size small_image_size(4, 4);
- const Size large_image_size(512, 512);
- const uint8_t image_color[] = {0, 0xff, 0, 0xff};
-
- // Create a small solid color green image of preferred format. This must
- // succeed in order for a GLImage to be conformant.
- scoped_refptr<GLImage> small_image = this->delegate_.CreateSolidColorImage(
- small_image_size, GLImageTestSupport::GetPreferredInternalFormat(),
- GLImageTestSupport::GetPreferredBufferFormat(), image_color);
- ASSERT_TRUE(small_image);
-
- // Create a large solid color green image of preferred format. This must
- // succeed in order for a GLImage to be conformant.
- scoped_refptr<GLImage> large_image = this->delegate_.CreateSolidColorImage(
- large_image_size, GLImageTestSupport::GetPreferredInternalFormat(),
- GLImageTestSupport::GetPreferredBufferFormat(), image_color);
- ASSERT_TRUE(large_image);
-
- // Verify that image size is correct.
- EXPECT_EQ(small_image->GetSize().ToString(), small_image_size.ToString());
- EXPECT_EQ(large_image->GetSize().ToString(), large_image_size.ToString());
-
- // Verify that internal format is correct.
- EXPECT_EQ(small_image->GetInternalFormat(),
- GLImageTestSupport::GetPreferredInternalFormat());
- EXPECT_EQ(large_image->GetInternalFormat(),
- GLImageTestSupport::GetPreferredInternalFormat());
-
- // Verify that destruction of images work correctly both when we have a
- // context and when we don't.
- small_image->Destroy(true /* have_context */);
- large_image->Destroy(false /* have_context */);
-}
-
-// The GLImageTest test case verifies the behaviour that is expected from a
-// GLImage in order to be conformant.
-REGISTER_TYPED_TEST_CASE_P(GLImageTest, CreateAndDestroy);
-
-template <typename GLImageTestDelegate>
-class GLImageCopyTest : public GLImageTest<GLImageTestDelegate> {};
-
-TYPED_TEST_CASE_P(GLImageCopyTest);
-
-TYPED_TEST_P(GLImageCopyTest, CopyTexImage) {
+// Copy image to texture. Support is optional. Texels should be updated if
+// supported, and left unchanged if not.
+TYPED_TEST_P(GLImageTest, CopyTexSubImage) {
const Size image_size(256, 256);
const uint8_t image_color[] = {0, 0xff, 0, 0xff};
const uint8_t texture_color[] = {0, 0, 0xff, 0xff};
@@ -133,9 +91,9 @@ TYPED_TEST_P(GLImageCopyTest, CopyTexImage) {
GLImageTestSupport::GetPreferredInternalFormat(),
GL_UNSIGNED_BYTE, pixels.get());
- // Copy |image| to |texture|.
- bool rv = image->CopyTexImage(GL_TEXTURE_2D);
- EXPECT_TRUE(rv);
+ // Attempt to copy |image| to |texture|.
+ // Returns true on success, false on failure.
+ bool rv = image->CopyTexSubImage(GL_TEXTURE_2D, Point(), Rect(image_size));
// clang-format off
const char kVertexShader[] = STRINGIZE(
@@ -203,7 +161,7 @@ TYPED_TEST_P(GLImageCopyTest, CopyTexImage) {
// Draw |texture| to viewport and read back pixels to check expectations.
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
GLTestHelper::CheckPixels(0, 0, image_size.width(), image_size.height(),
- image_color);
+ rv ? image_color : texture_color);
// Clean up.
glDeleteProgram(program);
@@ -215,9 +173,9 @@ TYPED_TEST_P(GLImageCopyTest, CopyTexImage) {
image->Destroy(true);
}
-// The GLImageCopyTest test case verifies that the GLImage implementation
-// handles CopyTexImage correctly.
-REGISTER_TYPED_TEST_CASE_P(GLImageCopyTest, CopyTexImage);
+// The GLImageTest test case verifies behaviour that is expected from a
+// GLImage in order to be conformant.
+REGISTER_TYPED_TEST_CASE_P(GLImageTest, CopyTexSubImage);
} // namespace gfx