| Index: content/common/gpu/texture_image_transport_surface.cc
|
| diff --git a/content/common/gpu/texture_image_transport_surface.cc b/content/common/gpu/texture_image_transport_surface.cc
|
| index 64848fed3982b98c3e88bd4f582309a0770c06e2..7fa269006a27910f6ddd9b682bda35872a1e7f0d 100644
|
| --- a/content/common/gpu/texture_image_transport_surface.cc
|
| +++ b/content/common/gpu/texture_image_transport_surface.cc
|
| @@ -16,17 +16,19 @@
|
| #include "content/public/common/content_switches.h"
|
| #include "gpu/command_buffer/service/context_group.h"
|
| #include "gpu/command_buffer/service/gpu_scheduler.h"
|
| -#include "gpu/command_buffer/service/texture_manager.h"
|
| +#include "gpu/command_buffer/service/texture_definition.h"
|
|
|
| using gpu::gles2::ContextGroup;
|
| +using gpu::gles2::MailboxManager;
|
| +using gpu::gles2::MailboxName;
|
| +using gpu::gles2::TextureDefinition;
|
| using gpu::gles2::TextureManager;
|
| -typedef TextureManager::TextureInfo TextureInfo;
|
|
|
| namespace content {
|
|
|
| TextureImageTransportSurface::Texture::Texture()
|
| - : client_id(0),
|
| - sent_to_client(false) {
|
| + : service_id(0),
|
| + surface_handle(0) {
|
| }
|
|
|
| TextureImageTransportSurface::Texture::~Texture() {
|
| @@ -37,17 +39,12 @@ TextureImageTransportSurface::TextureImageTransportSurface(
|
| GpuCommandBufferStub* stub,
|
| const gfx::GLSurfaceHandle& handle)
|
| : fbo_id_(0),
|
| - front_(0),
|
| stub_destroyed_(false),
|
| backbuffer_suggested_allocation_(true),
|
| frontbuffer_suggested_allocation_(true),
|
| - frontbuffer_is_protected_(true),
|
| - protection_state_id_(0),
|
| handle_(handle),
|
| - parent_stub_(NULL),
|
| is_swap_buffers_pending_(false),
|
| - did_unschedule_(false),
|
| - did_flip_(false) {
|
| + did_unschedule_(false) {
|
| helper_.reset(new ImageTransportHelper(this,
|
| manager,
|
| stub,
|
| @@ -60,39 +57,12 @@ TextureImageTransportSurface::~TextureImageTransportSurface() {
|
| }
|
|
|
| bool TextureImageTransportSurface::Initialize() {
|
| - GpuChannelManager* manager = helper_->manager();
|
| - GpuChannel* parent_channel = manager->LookupChannel(handle_.parent_client_id);
|
| - if (!parent_channel)
|
| - return false;
|
| + mailbox_manager_ =
|
| + helper_->stub()->decoder()->GetContextGroup()->mailbox_manager();
|
|
|
| - parent_stub_ = parent_channel->LookupCommandBuffer(handle_.parent_context_id);
|
| - if (!parent_stub_)
|
| - return false;
|
| -
|
| - parent_stub_->AddDestructionObserver(this);
|
| - TextureManager* texture_manager =
|
| - parent_stub_->decoder()->GetContextGroup()->texture_manager();
|
| - DCHECK(texture_manager);
|
| -
|
| - for (int i = 0; i < 2; ++i) {
|
| - Texture& texture = textures_[i];
|
| - texture.client_id = handle_.parent_texture_id[i];
|
| - texture.info = texture_manager->GetTextureInfo(texture.client_id);
|
| - if (!texture.info)
|
| - return false;
|
| -
|
| - if (!texture.info->target())
|
| - texture_manager->SetInfoTarget(texture.info, GL_TEXTURE_2D);
|
| - texture_manager->SetParameter(
|
| - texture.info, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
| - texture_manager->SetParameter(
|
| - texture.info, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
| - texture_manager->SetParameter(
|
| - texture.info, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
| - texture_manager->SetParameter(
|
| - texture.info, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
| - }
|
| + backbuffer_.surface_handle = 1;
|
|
|
| + GpuChannelManager* manager = helper_->manager();
|
| surface_ = manager->GetDefaultOffscreenSurface();
|
| if (!surface_.get())
|
| return false;
|
| @@ -100,19 +70,17 @@ bool TextureImageTransportSurface::Initialize() {
|
| if (!helper_->Initialize())
|
| return false;
|
|
|
| - const CommandLine* command_line = CommandLine::ForCurrentProcess();
|
| - if (command_line->HasSwitch(switches::kUIPrioritizeInGpuProcess))
|
| - helper_->SetPreemptByCounter(parent_channel->MessagesPendingCount());
|
| + GpuChannel* parent_channel = manager->LookupChannel(handle_.parent_client_id);
|
| + if (parent_channel) {
|
| + const CommandLine* command_line = CommandLine::ForCurrentProcess();
|
| + if (command_line->HasSwitch(switches::kUIPrioritizeInGpuProcess))
|
| + helper_->SetPreemptByCounter(parent_channel->MessagesPendingCount());
|
| + }
|
|
|
| return true;
|
| }
|
|
|
| void TextureImageTransportSurface::Destroy() {
|
| - if (parent_stub_) {
|
| - parent_stub_->decoder()->MakeCurrent();
|
| - ReleaseParentStub();
|
| - }
|
| -
|
| if (surface_.get())
|
| surface_ = NULL;
|
|
|
| @@ -149,10 +117,23 @@ bool TextureImageTransportSurface::OnMakeCurrent(gfx::GLContext* context) {
|
| return true;
|
| }
|
|
|
| + if (!context_.get()) {
|
| + DCHECK(helper_->stub());
|
| + context_ = helper_->stub()->decoder()->GetGLContext();
|
| + }
|
| +
|
| if (!fbo_id_) {
|
| glGenFramebuffersEXT(1, &fbo_id_);
|
| glBindFramebufferEXT(GL_FRAMEBUFFER, fbo_id_);
|
| - CreateBackTexture(gfx::Size(1, 1));
|
| + current_size_ = gfx::Size(1, 1);
|
| + helper_->stub()->AddDestructionObserver(this);
|
| + }
|
| +
|
| + // We could be receiving non-deferred GL commands, that is anything that does
|
| + // not need a framebuffer.
|
| + if (!backbuffer_.service_id && !is_swap_buffers_pending_ &&
|
| + backbuffer_suggested_allocation_) {
|
| + CreateBackTexture();
|
|
|
| #ifndef NDEBUG
|
| GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
|
| @@ -163,10 +144,7 @@ bool TextureImageTransportSurface::OnMakeCurrent(gfx::GLContext* context) {
|
| return false;
|
| }
|
| #endif
|
| - DCHECK(helper_->stub());
|
| - helper_->stub()->AddDestructionObserver(this);
|
| }
|
| -
|
| return true;
|
| }
|
|
|
| @@ -180,15 +158,11 @@ void TextureImageTransportSurface::SetBackbufferAllocation(bool allocation) {
|
| return;
|
| backbuffer_suggested_allocation_ = allocation;
|
|
|
| - if (!helper_->MakeCurrent())
|
| - return;
|
| -
|
| if (backbuffer_suggested_allocation_) {
|
| - DCHECK(!textures_[back()].info->service_id() ||
|
| - !textures_[back()].sent_to_client);
|
| - CreateBackTexture(textures_[back()].size);
|
| + DCHECK(!backbuffer_.service_id);
|
| + CreateBackTexture();
|
| } else {
|
| - ReleaseTexture(back());
|
| + ReleaseBackTexture();
|
| }
|
| }
|
|
|
| @@ -196,22 +170,10 @@ void TextureImageTransportSurface::SetFrontbufferAllocation(bool allocation) {
|
| if (frontbuffer_suggested_allocation_ == allocation)
|
| return;
|
| frontbuffer_suggested_allocation_ = allocation;
|
| - AdjustFrontBufferAllocation();
|
| -}
|
|
|
| -void TextureImageTransportSurface::AdjustFrontBufferAllocation() {
|
| - if (!helper_->MakeCurrent())
|
| - return;
|
| -
|
| - if (!frontbuffer_suggested_allocation_ && !frontbuffer_is_protected_ &&
|
| - textures_[front()].info->service_id()) {
|
| - ReleaseTexture(front());
|
| - if (textures_[front()].sent_to_client) {
|
| - GpuHostMsg_AcceleratedSurfaceRelease_Params params;
|
| - params.identifier = textures_[front()].client_id;
|
| - helper_->SendAcceleratedSurfaceRelease(params);
|
| - textures_[front()].sent_to_client = false;
|
| - }
|
| + if (!frontbuffer_suggested_allocation_) {
|
| + GpuHostMsg_AcceleratedSurfaceRelease_Params params;
|
| + helper_->SendAcceleratedSurfaceRelease(params);
|
| }
|
| }
|
|
|
| @@ -228,50 +190,47 @@ void* TextureImageTransportSurface::GetConfig() {
|
| }
|
|
|
| void TextureImageTransportSurface::OnResize(gfx::Size size) {
|
| - CreateBackTexture(size);
|
| + current_size_ = size;
|
| + CreateBackTexture();
|
| }
|
|
|
| void TextureImageTransportSurface::OnWillDestroyStub(
|
| GpuCommandBufferStub* stub) {
|
| - if (stub == parent_stub_) {
|
| - ReleaseParentStub();
|
| - helper_->SetPreemptByCounter(NULL);
|
| - } else {
|
| - DCHECK(stub == helper_->stub());
|
| - stub->RemoveDestructionObserver(this);
|
| + DCHECK(stub == helper_->stub());
|
| + stub->RemoveDestructionObserver(this);
|
|
|
| - // We are losing the stub owning us, this is our last chance to clean up the
|
| - // resources we allocated in the stub's context.
|
| - if (fbo_id_) {
|
| - glDeleteFramebuffersEXT(1, &fbo_id_);
|
| - CHECK_GL_ERROR();
|
| - fbo_id_ = 0;
|
| - }
|
| + GpuHostMsg_AcceleratedSurfaceRelease_Params params;
|
| + helper_->SendAcceleratedSurfaceRelease(params);
|
|
|
| - stub_destroyed_ = true;
|
| + ReleaseBackTexture();
|
| +
|
| + // We are losing the stub owning us, this is our last chance to clean up the
|
| + // resources we allocated in the stub's context.
|
| + if (fbo_id_) {
|
| + glDeleteFramebuffersEXT(1, &fbo_id_);
|
| + CHECK_GL_ERROR();
|
| + fbo_id_ = 0;
|
| }
|
| +
|
| + stub_destroyed_ = true;
|
| }
|
|
|
| bool TextureImageTransportSurface::SwapBuffers() {
|
| DCHECK(backbuffer_suggested_allocation_);
|
| - if (!frontbuffer_suggested_allocation_ || !frontbuffer_is_protected_)
|
| + if (!frontbuffer_suggested_allocation_)
|
| return true;
|
| - if (!parent_stub_) {
|
| - LOG(ERROR) << "SwapBuffers failed because no parent stub.";
|
| - return false;
|
| - }
|
|
|
| glFlush();
|
| - front_ = back();
|
| - previous_damage_rect_ = gfx::Rect(textures_[front()].size);
|
| + ProduceTexture(backbuffer_);
|
|
|
| - DCHECK(textures_[front()].client_id != 0);
|
| + // Do not allow destruction while we are still waiting for a swap ACK,
|
| + // so we do not leak a texture in the mailbox.
|
| + AddRef();
|
|
|
| + DCHECK(backbuffer_.size == current_size_);
|
| GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params;
|
| - params.surface_handle = textures_[front()].client_id;
|
| - params.size = textures_[front()].size;
|
| - params.protection_state_id = protection_state_id_;
|
| - params.skip_ack = false;
|
| + params.surface_handle = backbuffer_.surface_handle;
|
| + params.size = backbuffer_.size;
|
| helper_->SendAcceleratedSurfaceBuffersSwapped(params);
|
|
|
| DCHECK(!is_swap_buffers_pending_);
|
| @@ -282,68 +241,31 @@ bool TextureImageTransportSurface::SwapBuffers() {
|
| bool TextureImageTransportSurface::PostSubBuffer(
|
| int x, int y, int width, int height) {
|
| DCHECK(backbuffer_suggested_allocation_);
|
| - DCHECK(textures_[back()].info->service_id());
|
| - if (!frontbuffer_suggested_allocation_ || !frontbuffer_is_protected_)
|
| + if (!frontbuffer_suggested_allocation_)
|
| return true;
|
| - // If we are recreating the frontbuffer with this swap, make sure we are
|
| - // drawing a full frame.
|
| - DCHECK(textures_[front()].info->service_id() ||
|
| - (!x && !y && gfx::Size(width, height) == textures_[back()].size));
|
| - if (!parent_stub_) {
|
| - LOG(ERROR) << "PostSubBuffer failed because no parent stub.";
|
| - return false;
|
| - }
|
| -
|
| const gfx::Rect new_damage_rect(x, y, width, height);
|
| + DCHECK(gfx::Rect(gfx::Point(), current_size_).Contains(new_damage_rect));
|
|
|
| // An empty damage rect is a successful no-op.
|
| if (new_damage_rect.IsEmpty())
|
| return true;
|
|
|
| - int back_texture_service_id = textures_[back()].info->service_id();
|
| - int front_texture_service_id = textures_[front()].info->service_id();
|
| -
|
| - gfx::Size expected_size = textures_[back()].size;
|
| - bool surfaces_same_size = textures_[front()].size == expected_size;
|
| -
|
| - if (surfaces_same_size) {
|
| - std::vector<gfx::Rect> regions_to_copy;
|
| - GetRegionsToCopy(previous_damage_rect_, new_damage_rect, ®ions_to_copy);
|
| -
|
| - ScopedFrameBufferBinder fbo_binder(fbo_id_);
|
| - glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
|
| - GL_COLOR_ATTACHMENT0,
|
| - GL_TEXTURE_2D,
|
| - front_texture_service_id,
|
| - 0);
|
| - ScopedTextureBinder texture_binder(back_texture_service_id);
|
| -
|
| - for (size_t i = 0; i < regions_to_copy.size(); ++i) {
|
| - const gfx::Rect& region_to_copy = regions_to_copy[i];
|
| - if (!region_to_copy.IsEmpty()) {
|
| - glCopyTexSubImage2D(GL_TEXTURE_2D, 0, region_to_copy.x(),
|
| - region_to_copy.y(), region_to_copy.x(), region_to_copy.y(),
|
| - region_to_copy.width(), region_to_copy.height());
|
| - }
|
| - }
|
| - } else if (!surfaces_same_size && did_flip_) {
|
| - DCHECK(new_damage_rect == gfx::Rect(expected_size));
|
| - }
|
| -
|
| glFlush();
|
| - front_ = back();
|
| - previous_damage_rect_ = new_damage_rect;
|
| + ProduceTexture(backbuffer_);
|
| +
|
| + // Do not allow destruction while we are still waiting for a swap ACK,
|
| + // so we do not leak a texture in the mailbox.
|
| + AddRef();
|
|
|
| - DCHECK(textures_[front()].client_id);
|
| + DCHECK(current_size_ == backbuffer_.size);
|
|
|
| GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params params;
|
| - params.surface_handle = textures_[front()].client_id;
|
| - params.surface_size = textures_[front()].size;
|
| + params.surface_handle = backbuffer_.surface_handle;
|
| + params.surface_size = backbuffer_.size;
|
| params.x = x;
|
| params.y = y;
|
| params.width = width;
|
| params.height = height;
|
| - params.protection_state_id = protection_state_id_;
|
| helper_->SendAcceleratedSurfacePostSubBuffer(params);
|
|
|
| DCHECK(!is_swap_buffers_pending_);
|
| @@ -360,7 +282,7 @@ std::string TextureImageTransportSurface::GetExtensions() {
|
| }
|
|
|
| gfx::Size TextureImageTransportSurface::GetSize() {
|
| - gfx::Size size = textures_[back()].size;
|
| + gfx::Size size = current_size_;
|
|
|
| // OSMesa expects a non-zero size.
|
| return gfx::Size(size.width() == 0 ? 1 : size.width(),
|
| @@ -375,70 +297,60 @@ unsigned TextureImageTransportSurface::GetFormat() {
|
| return surface_.get() ? surface_->GetFormat() : 0;
|
| }
|
|
|
| -void TextureImageTransportSurface::OnSetFrontSurfaceIsProtected(
|
| - bool is_protected, uint32 protection_state_id) {
|
| - protection_state_id_ = protection_state_id;
|
| - if (frontbuffer_is_protected_ == is_protected)
|
| - return;
|
| - frontbuffer_is_protected_ = is_protected;
|
| - AdjustFrontBufferAllocation();
|
| -
|
| - // If surface is set to protected, and we haven't actually released it yet,
|
| - // we can set the ui surface handle now just by sending a swap message.
|
| - if (is_protected && textures_[front()].info->service_id() &&
|
| - textures_[front()].sent_to_client) {
|
| - GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params;
|
| - params.surface_handle = textures_[front()].client_id;
|
| - params.size = textures_[front()].size;
|
| - params.protection_state_id = protection_state_id_;
|
| - params.skip_ack = true;
|
| - helper_->SendAcceleratedSurfaceBuffersSwapped(params);
|
| - }
|
| -}
|
| -
|
| -void TextureImageTransportSurface::OnBufferPresented(bool presented,
|
| +void TextureImageTransportSurface::OnBufferPresented(uint64 surface_handle,
|
| uint32 sync_point) {
|
| if (sync_point == 0) {
|
| - BufferPresentedImpl(presented);
|
| + BufferPresentedImpl(surface_handle);
|
| } else {
|
| helper_->manager()->sync_point_manager()->AddSyncPointCallback(
|
| sync_point,
|
| base::Bind(&TextureImageTransportSurface::BufferPresentedImpl,
|
| - this->AsWeakPtr(),
|
| - presented));
|
| + this,
|
| + surface_handle));
|
| }
|
| -}
|
|
|
| -void TextureImageTransportSurface::BufferPresentedImpl(bool presented) {
|
| - DCHECK(is_swap_buffers_pending_);
|
| - is_swap_buffers_pending_ = false;
|
| + // Careful, we might get deleted now if we were only waiting for
|
| + // a final swap ACK.
|
| + Release();
|
| +}
|
|
|
| - if (presented) {
|
| - // If we had not flipped, the two frame damage tracking is inconsistent.
|
| - // So conservatively take the whole frame.
|
| - if (!did_flip_)
|
| - previous_damage_rect_ = gfx::Rect(textures_[front()].size);
|
| +void TextureImageTransportSurface::BufferPresentedImpl(uint64 surface_handle) {
|
| + DCHECK(!backbuffer_.service_id);
|
| + if (surface_handle) {
|
| + DCHECK(surface_handle == 1 || surface_handle == 2);
|
| + backbuffer_.surface_handle = surface_handle;
|
| + ConsumeTexture(backbuffer_);
|
| } else {
|
| - front_ = back();
|
| - previous_damage_rect_ = gfx::Rect(0, 0, 0, 0);
|
| + // We didn't get back a texture, so allocate 'the other' buffer.
|
| + backbuffer_.surface_handle = (backbuffer_.surface_handle == 1) ? 2 : 1;
|
| + mailbox_name(backbuffer_.surface_handle) = MailboxName();
|
| + }
|
| +
|
| + if (stub_destroyed_ && backbuffer_.service_id) {
|
| + // TODO(sievers): Remove this after changes to the mailbox to take ownership
|
| + // of the service ids.
|
| + DCHECK(context_.get() && surface_.get());
|
| + if (context_->MakeCurrent(surface_.get()))
|
| + glDeleteTextures(1, &backbuffer_.service_id);
|
| +
|
| + return;
|
| }
|
|
|
| - did_flip_ = presented;
|
| + DCHECK(is_swap_buffers_pending_);
|
| + is_swap_buffers_pending_ = false;
|
| +
|
| + // We should not have allowed the backbuffer to be discarded while the ack
|
| + // was pending.
|
| + DCHECK(backbuffer_suggested_allocation_);
|
|
|
| // We're relying on the fact that the parent context is
|
| // finished with it's context when it inserts the sync point that
|
| // triggers this callback.
|
| if (helper_->MakeCurrent()) {
|
| - if ((presented && textures_[front()].size != textures_[back()].size) ||
|
| - !textures_[back()].info->service_id() ||
|
| - !textures_[back()].sent_to_client) {
|
| - // We may get an ACK from a stale swap just to reschedule. In that case,
|
| - // we may not have a backbuffer suggestion and should not recreate one.
|
| - if (backbuffer_suggested_allocation_)
|
| - CreateBackTexture(textures_[front()].size);
|
| - } else {
|
| + if (backbuffer_.size != current_size_ || !backbuffer_.service_id)
|
| + CreateBackTexture();
|
| + else
|
| AttachBackTextureToFBO();
|
| - }
|
| }
|
|
|
| // Even if MakeCurrent fails, schedule anyway, to trigger the lost context
|
| @@ -453,94 +365,69 @@ void TextureImageTransportSurface::OnResizeViewACK() {
|
| NOTREACHED();
|
| }
|
|
|
| -void TextureImageTransportSurface::ReleaseTexture(int id) {
|
| - if (!parent_stub_)
|
| - return;
|
| - Texture& texture = textures_[id];
|
| - TextureInfo* info = texture.info;
|
| - DCHECK(info);
|
| -
|
| - GLuint service_id = info->service_id();
|
| - if (!service_id)
|
| +void TextureImageTransportSurface::ReleaseBackTexture() {
|
| + if (!backbuffer_.service_id)
|
| return;
|
| - info->SetServiceId(0);
|
|
|
| - {
|
| - ScopedFrameBufferBinder fbo_binder(fbo_id_);
|
| - glDeleteTextures(1, &service_id);
|
| - }
|
| + glDeleteTextures(1, &backbuffer_.service_id);
|
| + backbuffer_.service_id = 0;
|
| + mailbox_name(backbuffer_.surface_handle) = MailboxName();
|
| glFlush();
|
| CHECK_GL_ERROR();
|
| }
|
|
|
| -void TextureImageTransportSurface::CreateBackTexture(const gfx::Size& size) {
|
| - if (!parent_stub_)
|
| - return;
|
| - Texture& texture = textures_[back()];
|
| - TextureInfo* info = texture.info;
|
| - DCHECK(info);
|
| -
|
| - GLuint service_id = info->service_id();
|
| +void TextureImageTransportSurface::CreateBackTexture() {
|
| + // If |is_swap_buffers_pending| we are waiting for our backbuffer
|
| + // in the mailbox, so we shouldn't be reallocating it now.
|
| + DCHECK(!is_swap_buffers_pending_);
|
|
|
| - if (service_id && texture.size == size && texture.sent_to_client)
|
| + if (backbuffer_.service_id && backbuffer_.size == current_size_)
|
| return;
|
|
|
| - if (!service_id) {
|
| - glGenTextures(1, &service_id);
|
| - info->SetServiceId(service_id);
|
| + if (!backbuffer_.service_id) {
|
| + MailboxName new_mailbox_name;
|
| + MailboxName& name = mailbox_name(backbuffer_.surface_handle);
|
| + // This slot should be uninitialized.
|
| + DCHECK(!memcmp(&name, &new_mailbox_name, sizeof(MailboxName)));
|
| + mailbox_manager_->GenerateMailboxName(&new_mailbox_name);
|
| + name = new_mailbox_name;
|
| + glGenTextures(1, &backbuffer_.service_id);
|
| }
|
|
|
| - if (size != texture.size) {
|
| - texture.size = size;
|
| - TextureManager* texture_manager =
|
| - parent_stub_->decoder()->GetContextGroup()->texture_manager();
|
| - texture_manager->SetLevelInfo(
|
| - info,
|
| - GL_TEXTURE_2D,
|
| - 0,
|
| - GL_RGBA,
|
| - size.width(),
|
| - size.height(),
|
| - 1,
|
| - 0,
|
| - GL_RGBA,
|
| - GL_UNSIGNED_BYTE,
|
| - true);
|
| - }
|
| + backbuffer_.size = current_size_;
|
|
|
| {
|
| - ScopedTextureBinder texture_binder(service_id);
|
| + ScopedTextureBinder texture_binder(backbuffer_.service_id);
|
| glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
| glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_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);
|
| glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
|
| - size.width(), size.height(), 0,
|
| + current_size_.width(), current_size_.height(), 0,
|
| GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
| CHECK_GL_ERROR();
|
| }
|
|
|
| AttachBackTextureToFBO();
|
|
|
| + const MailboxName& name = mailbox_name(backbuffer_.surface_handle);
|
| +
|
| GpuHostMsg_AcceleratedSurfaceNew_Params params;
|
| - params.width = size.width();
|
| - params.height = size.height();
|
| - params.surface_handle = texture.client_id;
|
| + params.width = current_size_.width();
|
| + params.height = current_size_.height();
|
| + params.surface_handle = backbuffer_.surface_handle;
|
| + params.mailbox_name.append(
|
| + reinterpret_cast<const char*>(&name), sizeof(name));
|
| helper_->SendAcceleratedSurfaceNew(params);
|
| - texture.sent_to_client = true;
|
| }
|
|
|
| void TextureImageTransportSurface::AttachBackTextureToFBO() {
|
| - if (!parent_stub_)
|
| - return;
|
| - TextureInfo* info = textures_[back()].info;
|
| - DCHECK(info);
|
| -
|
| + DCHECK(backbuffer_.service_id);
|
| ScopedFrameBufferBinder fbo_binder(fbo_id_);
|
| glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
|
| GL_COLOR_ATTACHMENT0,
|
| GL_TEXTURE_2D,
|
| - info->service_id(),
|
| + backbuffer_.service_id,
|
| 0);
|
| glFlush();
|
| CHECK_GL_ERROR();
|
| @@ -548,24 +435,58 @@ void TextureImageTransportSurface::AttachBackTextureToFBO() {
|
| #ifndef NDEBUG
|
| GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
|
| if (status != GL_FRAMEBUFFER_COMPLETE) {
|
| - DLOG(ERROR) << "Framebuffer incomplete.";
|
| + DLOG(FATAL) << "Framebuffer incomplete: " << status;
|
| }
|
| #endif
|
| }
|
|
|
| -void TextureImageTransportSurface::ReleaseParentStub() {
|
| - DCHECK(parent_stub_);
|
| - parent_stub_->RemoveDestructionObserver(this);
|
| - for (int i = 0; i < 2; ++i) {
|
| - Texture& texture = textures_[i];
|
| - texture.info = NULL;
|
| - if (!texture.sent_to_client)
|
| - continue;
|
| - GpuHostMsg_AcceleratedSurfaceRelease_Params params;
|
| - params.identifier = texture.client_id;
|
| - helper_->SendAcceleratedSurfaceRelease(params);
|
| +void TextureImageTransportSurface::ConsumeTexture(Texture& texture) {
|
| + DCHECK(!texture.service_id);
|
| + DCHECK(texture.surface_handle == 1 || texture.surface_handle == 2);
|
| +
|
| + scoped_ptr<TextureDefinition> definition(mailbox_manager_->ConsumeTexture(
|
| + GL_TEXTURE_2D, mailbox_name(texture.surface_handle)));
|
| + if (definition.get()) {
|
| + texture.service_id = definition->ReleaseServiceId();
|
| + texture.size = gfx::Size(definition->level_infos()[0][0].width,
|
| + definition->level_infos()[0][0].height);
|
| }
|
| - parent_stub_ = NULL;
|
| +}
|
| +
|
| +void TextureImageTransportSurface::ProduceTexture(Texture& texture) {
|
| + DCHECK(texture.service_id);
|
| + DCHECK(texture.surface_handle == 1 || texture.surface_handle == 2);
|
| + TextureManager* texture_manager =
|
| + helper_->stub()->decoder()->GetContextGroup()->texture_manager();
|
| + DCHECK(texture.size.width() > 0 && texture.size.height() > 0);
|
| + TextureDefinition::LevelInfo info(
|
| + GL_TEXTURE_2D, GL_RGBA, texture.size.width(), texture.size.height(), 1,
|
| + 0, GL_RGBA, GL_UNSIGNED_BYTE, true);
|
| +
|
| + TextureDefinition::LevelInfos level_infos;
|
| + level_infos.resize(1);
|
| + level_infos[0].resize(texture_manager->MaxLevelsForTarget(GL_TEXTURE_2D));
|
| + level_infos[0][0] = info;
|
| + scoped_ptr<TextureDefinition> definition(new TextureDefinition(
|
| + GL_TEXTURE_2D,
|
| + texture.service_id,
|
| + GL_LINEAR,
|
| + GL_LINEAR,
|
| + GL_CLAMP_TO_EDGE,
|
| + GL_CLAMP_TO_EDGE,
|
| + GL_NONE,
|
| + true,
|
| + level_infos));
|
| + // Pass NULL as |owner| here to avoid errors from glConsumeTextureCHROMIUM()
|
| + // when the renderer context group goes away before the RWHV handles a pending
|
| + // ACK. We avoid leaking a texture in the mailbox by waiting for the final ACK
|
| + // at which point we consume the correct texture back.
|
| + mailbox_manager_->ProduceTexture(
|
| + GL_TEXTURE_2D,
|
| + mailbox_name(texture.surface_handle),
|
| + definition.release(),
|
| + NULL);
|
| + texture.service_id = 0;
|
| }
|
|
|
| } // namespace content
|
|
|