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 7078a3e972b41d247b976f96347942b6f2becab5..512bddaa563c46a9178d8308041208e4aac8f0f9 100644 |
--- a/content/common/gpu/texture_image_transport_surface.cc |
+++ b/content/common/gpu/texture_image_transport_surface.cc |
@@ -16,14 +16,15 @@ |
#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::TextureDefinition; |
using gpu::gles2::TextureManager; |
-typedef TextureManager::TextureInfo TextureInfo; |
TextureImageTransportSurface::Texture::Texture() |
- : client_id(0), |
+ : identifier(0), |
sent_to_client(false) { |
} |
@@ -42,7 +43,6 @@ TextureImageTransportSurface::TextureImageTransportSurface( |
frontbuffer_is_protected_(true), |
protection_state_id_(0), |
handle_(handle), |
- parent_stub_(NULL), |
is_swap_buffers_pending_(false), |
did_unschedule_(false) { |
helper_.reset(new ImageTransportHelper(this, |
@@ -56,40 +56,18 @@ TextureImageTransportSurface::~TextureImageTransportSurface() { |
Destroy(); |
} |
-bool TextureImageTransportSurface::Initialize() { |
- GpuChannelManager* manager = helper_->manager(); |
- GpuChannel* parent_channel = manager->LookupChannel(handle_.parent_client_id); |
- if (!parent_channel) |
- return false; |
- |
- 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); |
+uint32 TextureImageTransportSurface::GenerateId() { |
+ static int nextId = 0; |
+ return ++nextId; |
+} |
+bool TextureImageTransportSurface::Initialize() { |
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); |
+ texture.identifier = GenerateId(); |
piman
2012/10/17 23:47:20
They don't need to be globally unique, you can jus
|
} |
+ GpuChannelManager* manager = helper_->manager(); |
surface_ = manager->GetDefaultOffscreenSurface(); |
if (!surface_.get()) |
return false; |
@@ -97,17 +75,28 @@ 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()); |
+ // TODO: Can this go somewhere else? I guess somebody should still react to |
+ // the UI context being recreated and update the preempt counter to the new |
+ // channel. |
piman
2012/10/17 23:47:20
The way I imagine this, is to move it the channel
|
+ 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(); |
+ for (int i = 0; i < 2; ++i) { |
+ Texture& texture = textures_[i]; |
+ if (!texture.sent_to_client) |
+ continue; |
+ GpuHostMsg_AcceleratedSurfaceRelease_Params params; |
+ params.identifier = texture.identifier; |
+ texture.identifier = 0; |
+ helper_->SendAcceleratedSurfaceRelease(params); |
} |
if (surface_.get()) |
@@ -180,7 +169,7 @@ void TextureImageTransportSurface::SetBackbufferAllocation(bool allocation) { |
return; |
if (backbuffer_suggested_allocation_) { |
- DCHECK(!textures_[back()].info->service_id() || |
+ DCHECK(!textures_[back()].service_id || |
!textures_[back()].sent_to_client); |
CreateBackTexture(textures_[back()].size); |
} else { |
@@ -200,11 +189,12 @@ void TextureImageTransportSurface::AdjustFrontBufferAllocation() { |
return; |
if (!frontbuffer_suggested_allocation_ && !frontbuffer_is_protected_ && |
- textures_[front()].info->service_id()) { |
+ textures_[front()].service_id) { |
ReleaseTexture(front()); |
if (textures_[front()].sent_to_client) { |
GpuHostMsg_AcceleratedSurfaceRelease_Params params; |
- params.identifier = textures_[front()].client_id; |
+ params.identifier = textures_[front()].identifier; |
+ textures_[front()].identifier = 0; |
helper_->SendAcceleratedSurfaceRelease(params); |
textures_[front()].sent_to_client = false; |
} |
@@ -229,42 +219,39 @@ void TextureImageTransportSurface::OnResize(gfx::Size size) { |
void TextureImageTransportSurface::OnWillDestroyStub( |
GpuCommandBufferStub* stub) { |
- if (stub == parent_stub_) { |
+ // TODO |
+ /*if (stub == parent_stub_) { |
ReleaseParentStub(); |
helper_->SetPreemptByCounter(NULL); |
- } else { |
- 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; |
- } |
- |
- stub_destroyed_ = true; |
+ }*/ |
+ 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; |
} |
+ |
+ stub_destroyed_ = true; |
} |
bool TextureImageTransportSurface::SwapBuffers() { |
DCHECK(backbuffer_suggested_allocation_); |
if (!frontbuffer_suggested_allocation_ || !frontbuffer_is_protected_) |
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(textures_[front()]); |
- DCHECK(textures_[front()].client_id != 0); |
+ DCHECK(textures_[front()].identifier != 0); |
GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params; |
- params.surface_handle = textures_[front()].client_id; |
+ params.surface_handle = textures_[front()].identifier; |
params.protection_state_id = protection_state_id_; |
params.skip_ack = false; |
helper_->SendAcceleratedSurfaceBuffersSwapped(params); |
@@ -277,17 +264,13 @@ bool TextureImageTransportSurface::SwapBuffers() { |
bool TextureImageTransportSurface::PostSubBuffer( |
int x, int y, int width, int height) { |
DCHECK(backbuffer_suggested_allocation_); |
- DCHECK(textures_[back()].info->service_id()); |
+ DCHECK(textures_[back()].service_id); |
if (!frontbuffer_suggested_allocation_ || !frontbuffer_is_protected_) |
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() || |
+ DCHECK(textures_[front()].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); |
@@ -295,8 +278,8 @@ bool TextureImageTransportSurface::PostSubBuffer( |
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(); |
+ int back_texture_service_id = textures_[back()].service_id; |
+ int front_texture_service_id = textures_[front()].service_id; |
gfx::Size expected_size = textures_[back()].size; |
bool surfaces_same_size = textures_[front()].size == expected_size; |
@@ -328,11 +311,12 @@ bool TextureImageTransportSurface::PostSubBuffer( |
glFlush(); |
front_ = back(); |
previous_damage_rect_ = new_damage_rect; |
+ ProduceTexture(textures_[front()]); |
- DCHECK(textures_[front()].client_id); |
+ DCHECK(textures_[front()].identifier); |
GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params params; |
- params.surface_handle = textures_[front()].client_id; |
+ params.surface_handle = textures_[front()].identifier; |
params.x = x; |
params.y = y; |
params.width = width; |
@@ -379,10 +363,10 @@ void TextureImageTransportSurface::OnSetFrontSurfaceIsProtected( |
// 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() && |
+ if (is_protected && textures_[front()].service_id && |
textures_[front()].sent_to_client) { |
GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params; |
- params.surface_handle = textures_[front()].client_id; |
+ params.surface_handle = textures_[front()].identifier; |
params.protection_state_id = protection_state_id_; |
params.skip_ack = true; |
helper_->SendAcceleratedSurfaceBuffersSwapped(params); |
@@ -408,8 +392,11 @@ void TextureImageTransportSurface::BufferPresentedImpl() { |
// finished with it's context when it inserts the sync point that |
// triggers this callback. |
if (helper_->MakeCurrent()) { |
+ // TODO: Is this the right check to see if it was ever created and produced? |
+ if (!textures_[back()].service_id && textures_[back()].sent_to_client) |
+ ConsumeTexture(textures_[back()]); |
if (textures_[front()].size != textures_[back()].size || |
- !textures_[back()].info->service_id() || |
+ !textures_[back()].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. |
@@ -433,62 +420,34 @@ void TextureImageTransportSurface::OnResizeViewACK() { |
} |
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) |
+ if (!textures_[id].service_id) |
return; |
- info->SetServiceId(0); |
+ textures_[id].service_id = 0; |
{ |
content::ScopedFrameBufferBinder fbo_binder(fbo_id_); |
- glDeleteTextures(1, &service_id); |
+ glDeleteTextures(1, &textures_[id].service_id); |
} |
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(); |
- |
- if (service_id && texture.size == size && texture.sent_to_client) |
+ if (texture.service_id && texture.size == size && texture.sent_to_client) |
return; |
- if (!service_id) { |
- glGenTextures(1, &service_id); |
- info->SetServiceId(service_id); |
+ if (!texture.service_id) { |
+ glGenTextures(1, &texture.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); |
} |
{ |
- content::ScopedTextureBinder texture_binder(service_id); |
+ content::ScopedTextureBinder texture_binder(texture.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); |
@@ -501,25 +460,29 @@ void TextureImageTransportSurface::CreateBackTexture(const gfx::Size& size) { |
AttachBackTextureToFBO(); |
+ if (!texture.identifier) |
+ texture.identifier = GenerateId(); |
+ |
GpuHostMsg_AcceleratedSurfaceNew_Params params; |
params.width = size.width(); |
params.height = size.height(); |
- params.surface_handle = texture.client_id; |
+ MailboxManager* manager = helper_->stub()->decoder()->GetContextGroup()-> |
+ mailbox_manager(); |
+ gpu::gles2::MailboxName& name = texture.mailbox_name; |
+ manager->GenerateMailboxName(&name); |
+ params.mailbox_name.append((char*)name.key, sizeof(name.key)); |
+ params.mailbox_name.append((char*)name.signature, sizeof(name.signature)); |
+ params.surface_handle = texture.identifier; |
helper_->SendAcceleratedSurfaceNew(params); |
texture.sent_to_client = true; |
} |
void TextureImageTransportSurface::AttachBackTextureToFBO() { |
- if (!parent_stub_) |
- return; |
- TextureInfo* info = textures_[back()].info; |
- DCHECK(info); |
- |
content::ScopedFrameBufferBinder fbo_binder(fbo_id_); |
glFramebufferTexture2DEXT(GL_FRAMEBUFFER, |
GL_COLOR_ATTACHMENT0, |
GL_TEXTURE_2D, |
- info->service_id(), |
+ textures_[back()].service_id, |
0); |
glFlush(); |
CHECK_GL_ERROR(); |
@@ -527,22 +490,48 @@ void TextureImageTransportSurface::AttachBackTextureToFBO() { |
#ifndef NDEBUG |
GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); |
if (status != GL_FRAMEBUFFER_COMPLETE) { |
- DLOG(ERROR) << "Framebuffer incomplete."; |
+ DLOG(ERROR) << "Framebuffer incomplete: " << status; |
+ DCHECK(false); |
} |
#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); |
- } |
- parent_stub_ = NULL; |
+void TextureImageTransportSurface::ConsumeTexture(Texture& texture) { |
+ MailboxManager* manager = helper_->stub()->decoder()->GetContextGroup()-> |
+ mailbox_manager(); |
+ scoped_ptr<TextureDefinition> definition(manager->ConsumeTexture( |
+ GL_TEXTURE_2D, texture.mailbox_name)); |
+ if (definition.get()) |
+ texture.service_id = definition->ReleaseServiceId(); |
+ |
+ // TODO: This can happen if the other side did not put the texture back |
+ // before the sync point, or that other context was lost. |
+ DCHECK(definition.get()); |
+} |
+ |
+void TextureImageTransportSurface::ProduceTexture(Texture& texture) { |
+ TextureManager* texture_manager = |
+ helper_->stub()->decoder()->GetContextGroup()->texture_manager(); |
+ MailboxManager* mailbox_manager = |
+ helper_->stub()->decoder()->GetContextGroup()->mailbox_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, |
+ true, |
+ level_infos)); |
+ mailbox_manager->ProduceTexture( |
+ GL_TEXTURE_2D, |
+ texture.mailbox_name, |
+ definition.release(), |
+ helper_->stub()->decoder()->GetContextGroup()->texture_manager()); |
+ texture.service_id = 0; |
} |