Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/common/gpu/texture_image_transport_surface.h" | 5 #include "content/common/gpu/texture_image_transport_surface.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| 11 #include "content/common/gpu/gl_scoped_binders.h" | 11 #include "content/common/gpu/gl_scoped_binders.h" |
| 12 #include "content/common/gpu/gpu_channel.h" | 12 #include "content/common/gpu/gpu_channel.h" |
| 13 #include "content/common/gpu/gpu_channel_manager.h" | 13 #include "content/common/gpu/gpu_channel_manager.h" |
| 14 #include "content/common/gpu/gpu_messages.h" | 14 #include "content/common/gpu/gpu_messages.h" |
| 15 #include "content/common/gpu/sync_point_manager.h" | 15 #include "content/common/gpu/sync_point_manager.h" |
| 16 #include "content/public/common/content_switches.h" | 16 #include "content/public/common/content_switches.h" |
| 17 #include "gpu/command_buffer/service/context_group.h" | 17 #include "gpu/command_buffer/service/context_group.h" |
| 18 #include "gpu/command_buffer/service/gpu_scheduler.h" | 18 #include "gpu/command_buffer/service/gpu_scheduler.h" |
| 19 #include "gpu/command_buffer/service/texture_manager.h" | 19 #include "gpu/command_buffer/service/texture_definition.h" |
| 20 | 20 |
| 21 using gpu::gles2::ContextGroup; | 21 using gpu::gles2::ContextGroup; |
| 22 using gpu::gles2::MailboxManager; | |
| 23 using gpu::gles2::TextureDefinition; | |
| 22 using gpu::gles2::TextureManager; | 24 using gpu::gles2::TextureManager; |
| 23 typedef TextureManager::TextureInfo TextureInfo; | |
| 24 | 25 |
| 25 TextureImageTransportSurface::Texture::Texture() | 26 TextureImageTransportSurface::Texture::Texture() |
| 26 : client_id(0), | 27 : identifier(0), |
| 27 sent_to_client(false) { | 28 sent_to_client(false) { |
| 28 } | 29 } |
| 29 | 30 |
| 30 TextureImageTransportSurface::Texture::~Texture() { | 31 TextureImageTransportSurface::Texture::~Texture() { |
| 31 } | 32 } |
| 32 | 33 |
| 33 TextureImageTransportSurface::TextureImageTransportSurface( | 34 TextureImageTransportSurface::TextureImageTransportSurface( |
| 34 GpuChannelManager* manager, | 35 GpuChannelManager* manager, |
| 35 GpuCommandBufferStub* stub, | 36 GpuCommandBufferStub* stub, |
| 36 const gfx::GLSurfaceHandle& handle) | 37 const gfx::GLSurfaceHandle& handle) |
| 37 : fbo_id_(0), | 38 : fbo_id_(0), |
| 38 front_(0), | 39 front_(0), |
| 39 stub_destroyed_(false), | 40 stub_destroyed_(false), |
| 40 backbuffer_suggested_allocation_(true), | 41 backbuffer_suggested_allocation_(true), |
| 41 frontbuffer_suggested_allocation_(true), | 42 frontbuffer_suggested_allocation_(true), |
| 42 frontbuffer_is_protected_(true), | 43 frontbuffer_is_protected_(true), |
| 43 protection_state_id_(0), | 44 protection_state_id_(0), |
| 44 handle_(handle), | 45 handle_(handle), |
| 45 parent_stub_(NULL), | |
| 46 is_swap_buffers_pending_(false), | 46 is_swap_buffers_pending_(false), |
| 47 did_unschedule_(false) { | 47 did_unschedule_(false) { |
| 48 helper_.reset(new ImageTransportHelper(this, | 48 helper_.reset(new ImageTransportHelper(this, |
| 49 manager, | 49 manager, |
| 50 stub, | 50 stub, |
| 51 gfx::kNullPluginWindow)); | 51 gfx::kNullPluginWindow)); |
| 52 } | 52 } |
| 53 | 53 |
| 54 TextureImageTransportSurface::~TextureImageTransportSurface() { | 54 TextureImageTransportSurface::~TextureImageTransportSurface() { |
| 55 DCHECK(stub_destroyed_); | 55 DCHECK(stub_destroyed_); |
| 56 Destroy(); | 56 Destroy(); |
| 57 } | 57 } |
| 58 | 58 |
| 59 uint32 TextureImageTransportSurface::GenerateId() { | |
| 60 static int nextId = 0; | |
| 61 return ++nextId; | |
| 62 } | |
| 63 | |
| 59 bool TextureImageTransportSurface::Initialize() { | 64 bool TextureImageTransportSurface::Initialize() { |
| 60 GpuChannelManager* manager = helper_->manager(); | |
| 61 GpuChannel* parent_channel = manager->LookupChannel(handle_.parent_client_id); | |
| 62 if (!parent_channel) | |
| 63 return false; | |
| 64 | |
| 65 parent_stub_ = parent_channel->LookupCommandBuffer(handle_.parent_context_id); | |
| 66 if (!parent_stub_) | |
| 67 return false; | |
| 68 | |
| 69 parent_stub_->AddDestructionObserver(this); | |
| 70 TextureManager* texture_manager = | |
| 71 parent_stub_->decoder()->GetContextGroup()->texture_manager(); | |
| 72 DCHECK(texture_manager); | |
| 73 | |
| 74 for (int i = 0; i < 2; ++i) { | 65 for (int i = 0; i < 2; ++i) { |
| 75 Texture& texture = textures_[i]; | 66 Texture& texture = textures_[i]; |
| 76 texture.client_id = handle_.parent_texture_id[i]; | 67 texture.identifier = GenerateId(); |
|
piman
2012/10/17 23:47:20
They don't need to be globally unique, you can jus
| |
| 77 texture.info = texture_manager->GetTextureInfo(texture.client_id); | |
| 78 if (!texture.info) | |
| 79 return false; | |
| 80 | |
| 81 if (!texture.info->target()) | |
| 82 texture_manager->SetInfoTarget(texture.info, GL_TEXTURE_2D); | |
| 83 texture_manager->SetParameter( | |
| 84 texture.info, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | |
| 85 texture_manager->SetParameter( | |
| 86 texture.info, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | |
| 87 texture_manager->SetParameter( | |
| 88 texture.info, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | |
| 89 texture_manager->SetParameter( | |
| 90 texture.info, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | |
| 91 } | 68 } |
| 92 | 69 |
| 70 GpuChannelManager* manager = helper_->manager(); | |
| 93 surface_ = manager->GetDefaultOffscreenSurface(); | 71 surface_ = manager->GetDefaultOffscreenSurface(); |
| 94 if (!surface_.get()) | 72 if (!surface_.get()) |
| 95 return false; | 73 return false; |
| 96 | 74 |
| 97 if (!helper_->Initialize()) | 75 if (!helper_->Initialize()) |
| 98 return false; | 76 return false; |
| 99 | 77 |
| 100 const CommandLine* command_line = CommandLine::ForCurrentProcess(); | 78 // TODO: Can this go somewhere else? I guess somebody should still react to |
| 101 if (command_line->HasSwitch(switches::kUIPrioritizeInGpuProcess)) | 79 // the UI context being recreated and update the preempt counter to the new |
| 102 helper_->SetPreemptByCounter(parent_channel->MessagesPendingCount()); | 80 // channel. |
|
piman
2012/10/17 23:47:20
The way I imagine this, is to move it the channel
| |
| 81 GpuChannel* parent_channel = manager->LookupChannel(handle_.parent_client_id); | |
| 82 if (parent_channel) { | |
| 83 const CommandLine* command_line = CommandLine::ForCurrentProcess(); | |
| 84 if (command_line->HasSwitch(switches::kUIPrioritizeInGpuProcess)) | |
| 85 helper_->SetPreemptByCounter(parent_channel->MessagesPendingCount()); | |
| 86 } | |
| 103 | 87 |
| 104 return true; | 88 return true; |
| 105 } | 89 } |
| 106 | 90 |
| 107 void TextureImageTransportSurface::Destroy() { | 91 void TextureImageTransportSurface::Destroy() { |
| 108 if (parent_stub_) { | 92 for (int i = 0; i < 2; ++i) { |
| 109 parent_stub_->decoder()->MakeCurrent(); | 93 Texture& texture = textures_[i]; |
| 110 ReleaseParentStub(); | 94 if (!texture.sent_to_client) |
| 95 continue; | |
| 96 GpuHostMsg_AcceleratedSurfaceRelease_Params params; | |
| 97 params.identifier = texture.identifier; | |
| 98 texture.identifier = 0; | |
| 99 helper_->SendAcceleratedSurfaceRelease(params); | |
| 111 } | 100 } |
| 112 | 101 |
| 113 if (surface_.get()) | 102 if (surface_.get()) |
| 114 surface_ = NULL; | 103 surface_ = NULL; |
| 115 | 104 |
| 116 helper_->Destroy(); | 105 helper_->Destroy(); |
| 117 } | 106 } |
| 118 | 107 |
| 119 bool TextureImageTransportSurface::DeferDraws() { | 108 bool TextureImageTransportSurface::DeferDraws() { |
| 120 // The command buffer hit a draw/clear command that could clobber the | 109 // The command buffer hit a draw/clear command that could clobber the |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 173 | 162 |
| 174 void TextureImageTransportSurface::SetBackbufferAllocation(bool allocation) { | 163 void TextureImageTransportSurface::SetBackbufferAllocation(bool allocation) { |
| 175 if (backbuffer_suggested_allocation_ == allocation) | 164 if (backbuffer_suggested_allocation_ == allocation) |
| 176 return; | 165 return; |
| 177 backbuffer_suggested_allocation_ = allocation; | 166 backbuffer_suggested_allocation_ = allocation; |
| 178 | 167 |
| 179 if (!helper_->MakeCurrent()) | 168 if (!helper_->MakeCurrent()) |
| 180 return; | 169 return; |
| 181 | 170 |
| 182 if (backbuffer_suggested_allocation_) { | 171 if (backbuffer_suggested_allocation_) { |
| 183 DCHECK(!textures_[back()].info->service_id() || | 172 DCHECK(!textures_[back()].service_id || |
| 184 !textures_[back()].sent_to_client); | 173 !textures_[back()].sent_to_client); |
| 185 CreateBackTexture(textures_[back()].size); | 174 CreateBackTexture(textures_[back()].size); |
| 186 } else { | 175 } else { |
| 187 ReleaseTexture(back()); | 176 ReleaseTexture(back()); |
| 188 } | 177 } |
| 189 } | 178 } |
| 190 | 179 |
| 191 void TextureImageTransportSurface::SetFrontbufferAllocation(bool allocation) { | 180 void TextureImageTransportSurface::SetFrontbufferAllocation(bool allocation) { |
| 192 if (frontbuffer_suggested_allocation_ == allocation) | 181 if (frontbuffer_suggested_allocation_ == allocation) |
| 193 return; | 182 return; |
| 194 frontbuffer_suggested_allocation_ = allocation; | 183 frontbuffer_suggested_allocation_ = allocation; |
| 195 AdjustFrontBufferAllocation(); | 184 AdjustFrontBufferAllocation(); |
| 196 } | 185 } |
| 197 | 186 |
| 198 void TextureImageTransportSurface::AdjustFrontBufferAllocation() { | 187 void TextureImageTransportSurface::AdjustFrontBufferAllocation() { |
| 199 if (!helper_->MakeCurrent()) | 188 if (!helper_->MakeCurrent()) |
| 200 return; | 189 return; |
| 201 | 190 |
| 202 if (!frontbuffer_suggested_allocation_ && !frontbuffer_is_protected_ && | 191 if (!frontbuffer_suggested_allocation_ && !frontbuffer_is_protected_ && |
| 203 textures_[front()].info->service_id()) { | 192 textures_[front()].service_id) { |
| 204 ReleaseTexture(front()); | 193 ReleaseTexture(front()); |
| 205 if (textures_[front()].sent_to_client) { | 194 if (textures_[front()].sent_to_client) { |
| 206 GpuHostMsg_AcceleratedSurfaceRelease_Params params; | 195 GpuHostMsg_AcceleratedSurfaceRelease_Params params; |
| 207 params.identifier = textures_[front()].client_id; | 196 params.identifier = textures_[front()].identifier; |
| 197 textures_[front()].identifier = 0; | |
| 208 helper_->SendAcceleratedSurfaceRelease(params); | 198 helper_->SendAcceleratedSurfaceRelease(params); |
| 209 textures_[front()].sent_to_client = false; | 199 textures_[front()].sent_to_client = false; |
| 210 } | 200 } |
| 211 } | 201 } |
| 212 } | 202 } |
| 213 | 203 |
| 214 void* TextureImageTransportSurface::GetShareHandle() { | 204 void* TextureImageTransportSurface::GetShareHandle() { |
| 215 return GetHandle(); | 205 return GetHandle(); |
| 216 } | 206 } |
| 217 | 207 |
| 218 void* TextureImageTransportSurface::GetDisplay() { | 208 void* TextureImageTransportSurface::GetDisplay() { |
| 219 return surface_.get() ? surface_->GetDisplay() : NULL; | 209 return surface_.get() ? surface_->GetDisplay() : NULL; |
| 220 } | 210 } |
| 221 | 211 |
| 222 void* TextureImageTransportSurface::GetConfig() { | 212 void* TextureImageTransportSurface::GetConfig() { |
| 223 return surface_.get() ? surface_->GetConfig() : NULL; | 213 return surface_.get() ? surface_->GetConfig() : NULL; |
| 224 } | 214 } |
| 225 | 215 |
| 226 void TextureImageTransportSurface::OnResize(gfx::Size size) { | 216 void TextureImageTransportSurface::OnResize(gfx::Size size) { |
| 227 CreateBackTexture(size); | 217 CreateBackTexture(size); |
| 228 } | 218 } |
| 229 | 219 |
| 230 void TextureImageTransportSurface::OnWillDestroyStub( | 220 void TextureImageTransportSurface::OnWillDestroyStub( |
| 231 GpuCommandBufferStub* stub) { | 221 GpuCommandBufferStub* stub) { |
| 232 if (stub == parent_stub_) { | 222 // TODO |
| 223 /*if (stub == parent_stub_) { | |
| 233 ReleaseParentStub(); | 224 ReleaseParentStub(); |
| 234 helper_->SetPreemptByCounter(NULL); | 225 helper_->SetPreemptByCounter(NULL); |
| 235 } else { | 226 }*/ |
| 236 DCHECK(stub == helper_->stub()); | 227 DCHECK(stub == helper_->stub()); |
| 237 stub->RemoveDestructionObserver(this); | 228 stub->RemoveDestructionObserver(this); |
| 238 | 229 |
| 239 // We are losing the stub owning us, this is our last chance to clean up the | 230 // We are losing the stub owning us, this is our last chance to clean up the |
| 240 // resources we allocated in the stub's context. | 231 // resources we allocated in the stub's context. |
| 241 if (fbo_id_) { | 232 if (fbo_id_) { |
| 242 glDeleteFramebuffersEXT(1, &fbo_id_); | 233 glDeleteFramebuffersEXT(1, &fbo_id_); |
| 243 CHECK_GL_ERROR(); | 234 CHECK_GL_ERROR(); |
| 244 fbo_id_ = 0; | 235 fbo_id_ = 0; |
| 245 } | 236 } |
| 246 | 237 |
| 247 stub_destroyed_ = true; | 238 stub_destroyed_ = true; |
| 248 } | |
| 249 } | 239 } |
| 250 | 240 |
| 251 bool TextureImageTransportSurface::SwapBuffers() { | 241 bool TextureImageTransportSurface::SwapBuffers() { |
| 252 DCHECK(backbuffer_suggested_allocation_); | 242 DCHECK(backbuffer_suggested_allocation_); |
| 253 if (!frontbuffer_suggested_allocation_ || !frontbuffer_is_protected_) | 243 if (!frontbuffer_suggested_allocation_ || !frontbuffer_is_protected_) |
| 254 return true; | 244 return true; |
| 255 if (!parent_stub_) { | |
| 256 LOG(ERROR) << "SwapBuffers failed because no parent stub."; | |
| 257 return false; | |
| 258 } | |
| 259 | 245 |
| 260 glFlush(); | 246 glFlush(); |
| 261 front_ = back(); | 247 front_ = back(); |
| 262 previous_damage_rect_ = gfx::Rect(textures_[front()].size); | 248 previous_damage_rect_ = gfx::Rect(textures_[front()].size); |
| 249 ProduceTexture(textures_[front()]); | |
| 263 | 250 |
| 264 DCHECK(textures_[front()].client_id != 0); | 251 DCHECK(textures_[front()].identifier != 0); |
| 265 | 252 |
| 266 GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params; | 253 GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params; |
| 267 params.surface_handle = textures_[front()].client_id; | 254 params.surface_handle = textures_[front()].identifier; |
| 268 params.protection_state_id = protection_state_id_; | 255 params.protection_state_id = protection_state_id_; |
| 269 params.skip_ack = false; | 256 params.skip_ack = false; |
| 270 helper_->SendAcceleratedSurfaceBuffersSwapped(params); | 257 helper_->SendAcceleratedSurfaceBuffersSwapped(params); |
| 271 | 258 |
| 272 DCHECK(!is_swap_buffers_pending_); | 259 DCHECK(!is_swap_buffers_pending_); |
| 273 is_swap_buffers_pending_ = true; | 260 is_swap_buffers_pending_ = true; |
| 274 return true; | 261 return true; |
| 275 } | 262 } |
| 276 | 263 |
| 277 bool TextureImageTransportSurface::PostSubBuffer( | 264 bool TextureImageTransportSurface::PostSubBuffer( |
| 278 int x, int y, int width, int height) { | 265 int x, int y, int width, int height) { |
| 279 DCHECK(backbuffer_suggested_allocation_); | 266 DCHECK(backbuffer_suggested_allocation_); |
| 280 DCHECK(textures_[back()].info->service_id()); | 267 DCHECK(textures_[back()].service_id); |
| 281 if (!frontbuffer_suggested_allocation_ || !frontbuffer_is_protected_) | 268 if (!frontbuffer_suggested_allocation_ || !frontbuffer_is_protected_) |
| 282 return true; | 269 return true; |
| 283 // If we are recreating the frontbuffer with this swap, make sure we are | 270 // If we are recreating the frontbuffer with this swap, make sure we are |
| 284 // drawing a full frame. | 271 // drawing a full frame. |
| 285 DCHECK(textures_[front()].info->service_id() || | 272 DCHECK(textures_[front()].service_id || |
| 286 (!x && !y && gfx::Size(width, height) == textures_[back()].size)); | 273 (!x && !y && gfx::Size(width, height) == textures_[back()].size)); |
| 287 if (!parent_stub_) { | |
| 288 LOG(ERROR) << "PostSubBuffer failed because no parent stub."; | |
| 289 return false; | |
| 290 } | |
| 291 | 274 |
| 292 const gfx::Rect new_damage_rect(x, y, width, height); | 275 const gfx::Rect new_damage_rect(x, y, width, height); |
| 293 | 276 |
| 294 // An empty damage rect is a successful no-op. | 277 // An empty damage rect is a successful no-op. |
| 295 if (new_damage_rect.IsEmpty()) | 278 if (new_damage_rect.IsEmpty()) |
| 296 return true; | 279 return true; |
| 297 | 280 |
| 298 int back_texture_service_id = textures_[back()].info->service_id(); | 281 int back_texture_service_id = textures_[back()].service_id; |
| 299 int front_texture_service_id = textures_[front()].info->service_id(); | 282 int front_texture_service_id = textures_[front()].service_id; |
| 300 | 283 |
| 301 gfx::Size expected_size = textures_[back()].size; | 284 gfx::Size expected_size = textures_[back()].size; |
| 302 bool surfaces_same_size = textures_[front()].size == expected_size; | 285 bool surfaces_same_size = textures_[front()].size == expected_size; |
| 303 | 286 |
| 304 if (surfaces_same_size) { | 287 if (surfaces_same_size) { |
| 305 std::vector<gfx::Rect> regions_to_copy; | 288 std::vector<gfx::Rect> regions_to_copy; |
| 306 GetRegionsToCopy(previous_damage_rect_, new_damage_rect, ®ions_to_copy); | 289 GetRegionsToCopy(previous_damage_rect_, new_damage_rect, ®ions_to_copy); |
| 307 | 290 |
| 308 content::ScopedFrameBufferBinder fbo_binder(fbo_id_); | 291 content::ScopedFrameBufferBinder fbo_binder(fbo_id_); |
| 309 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, | 292 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 321 region_to_copy.width(), region_to_copy.height()); | 304 region_to_copy.width(), region_to_copy.height()); |
| 322 } | 305 } |
| 323 } | 306 } |
| 324 } else { | 307 } else { |
| 325 DCHECK(new_damage_rect == gfx::Rect(expected_size)); | 308 DCHECK(new_damage_rect == gfx::Rect(expected_size)); |
| 326 } | 309 } |
| 327 | 310 |
| 328 glFlush(); | 311 glFlush(); |
| 329 front_ = back(); | 312 front_ = back(); |
| 330 previous_damage_rect_ = new_damage_rect; | 313 previous_damage_rect_ = new_damage_rect; |
| 314 ProduceTexture(textures_[front()]); | |
| 331 | 315 |
| 332 DCHECK(textures_[front()].client_id); | 316 DCHECK(textures_[front()].identifier); |
| 333 | 317 |
| 334 GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params params; | 318 GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params params; |
| 335 params.surface_handle = textures_[front()].client_id; | 319 params.surface_handle = textures_[front()].identifier; |
| 336 params.x = x; | 320 params.x = x; |
| 337 params.y = y; | 321 params.y = y; |
| 338 params.width = width; | 322 params.width = width; |
| 339 params.height = height; | 323 params.height = height; |
| 340 params.protection_state_id = protection_state_id_; | 324 params.protection_state_id = protection_state_id_; |
| 341 helper_->SendAcceleratedSurfacePostSubBuffer(params); | 325 helper_->SendAcceleratedSurfacePostSubBuffer(params); |
| 342 | 326 |
| 343 DCHECK(!is_swap_buffers_pending_); | 327 DCHECK(!is_swap_buffers_pending_); |
| 344 is_swap_buffers_pending_ = true; | 328 is_swap_buffers_pending_ = true; |
| 345 return true; | 329 return true; |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 372 void TextureImageTransportSurface::OnSetFrontSurfaceIsProtected( | 356 void TextureImageTransportSurface::OnSetFrontSurfaceIsProtected( |
| 373 bool is_protected, uint32 protection_state_id) { | 357 bool is_protected, uint32 protection_state_id) { |
| 374 protection_state_id_ = protection_state_id; | 358 protection_state_id_ = protection_state_id; |
| 375 if (frontbuffer_is_protected_ == is_protected) | 359 if (frontbuffer_is_protected_ == is_protected) |
| 376 return; | 360 return; |
| 377 frontbuffer_is_protected_ = is_protected; | 361 frontbuffer_is_protected_ = is_protected; |
| 378 AdjustFrontBufferAllocation(); | 362 AdjustFrontBufferAllocation(); |
| 379 | 363 |
| 380 // If surface is set to protected, and we haven't actually released it yet, | 364 // If surface is set to protected, and we haven't actually released it yet, |
| 381 // we can set the ui surface handle now just by sending a swap message. | 365 // we can set the ui surface handle now just by sending a swap message. |
| 382 if (is_protected && textures_[front()].info->service_id() && | 366 if (is_protected && textures_[front()].service_id && |
| 383 textures_[front()].sent_to_client) { | 367 textures_[front()].sent_to_client) { |
| 384 GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params; | 368 GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params; |
| 385 params.surface_handle = textures_[front()].client_id; | 369 params.surface_handle = textures_[front()].identifier; |
| 386 params.protection_state_id = protection_state_id_; | 370 params.protection_state_id = protection_state_id_; |
| 387 params.skip_ack = true; | 371 params.skip_ack = true; |
| 388 helper_->SendAcceleratedSurfaceBuffersSwapped(params); | 372 helper_->SendAcceleratedSurfaceBuffersSwapped(params); |
| 389 } | 373 } |
| 390 } | 374 } |
| 391 | 375 |
| 392 void TextureImageTransportSurface::OnBufferPresented(uint32 sync_point) { | 376 void TextureImageTransportSurface::OnBufferPresented(uint32 sync_point) { |
| 393 if (sync_point == 0) { | 377 if (sync_point == 0) { |
| 394 BufferPresentedImpl(); | 378 BufferPresentedImpl(); |
| 395 } else { | 379 } else { |
| 396 helper_->manager()->sync_point_manager()->AddSyncPointCallback( | 380 helper_->manager()->sync_point_manager()->AddSyncPointCallback( |
| 397 sync_point, | 381 sync_point, |
| 398 base::Bind(&TextureImageTransportSurface::BufferPresentedImpl, | 382 base::Bind(&TextureImageTransportSurface::BufferPresentedImpl, |
| 399 this->AsWeakPtr())); | 383 this->AsWeakPtr())); |
| 400 } | 384 } |
| 401 } | 385 } |
| 402 | 386 |
| 403 void TextureImageTransportSurface::BufferPresentedImpl() { | 387 void TextureImageTransportSurface::BufferPresentedImpl() { |
| 404 DCHECK(is_swap_buffers_pending_); | 388 DCHECK(is_swap_buffers_pending_); |
| 405 is_swap_buffers_pending_ = false; | 389 is_swap_buffers_pending_ = false; |
| 406 | 390 |
| 407 // We're relying on the fact that the parent context is | 391 // We're relying on the fact that the parent context is |
| 408 // finished with it's context when it inserts the sync point that | 392 // finished with it's context when it inserts the sync point that |
| 409 // triggers this callback. | 393 // triggers this callback. |
| 410 if (helper_->MakeCurrent()) { | 394 if (helper_->MakeCurrent()) { |
| 395 // TODO: Is this the right check to see if it was ever created and produced? | |
| 396 if (!textures_[back()].service_id && textures_[back()].sent_to_client) | |
| 397 ConsumeTexture(textures_[back()]); | |
| 411 if (textures_[front()].size != textures_[back()].size || | 398 if (textures_[front()].size != textures_[back()].size || |
| 412 !textures_[back()].info->service_id() || | 399 !textures_[back()].service_id || |
| 413 !textures_[back()].sent_to_client) { | 400 !textures_[back()].sent_to_client) { |
| 414 // We may get an ACK from a stale swap just to reschedule. In that case, | 401 // We may get an ACK from a stale swap just to reschedule. In that case, |
| 415 // we may not have a backbuffer suggestion and should not recreate one. | 402 // we may not have a backbuffer suggestion and should not recreate one. |
| 416 if (backbuffer_suggested_allocation_) | 403 if (backbuffer_suggested_allocation_) |
| 417 CreateBackTexture(textures_[front()].size); | 404 CreateBackTexture(textures_[front()].size); |
| 418 } else { | 405 } else { |
| 419 AttachBackTextureToFBO(); | 406 AttachBackTextureToFBO(); |
| 420 } | 407 } |
| 421 } | 408 } |
| 422 | 409 |
| 423 // Even if MakeCurrent fails, schedule anyway, to trigger the lost context | 410 // Even if MakeCurrent fails, schedule anyway, to trigger the lost context |
| 424 // logic. | 411 // logic. |
| 425 if (did_unschedule_) { | 412 if (did_unschedule_) { |
| 426 did_unschedule_ = false; | 413 did_unschedule_ = false; |
| 427 helper_->SetScheduled(true); | 414 helper_->SetScheduled(true); |
| 428 } | 415 } |
| 429 } | 416 } |
| 430 | 417 |
| 431 void TextureImageTransportSurface::OnResizeViewACK() { | 418 void TextureImageTransportSurface::OnResizeViewACK() { |
| 432 NOTREACHED(); | 419 NOTREACHED(); |
| 433 } | 420 } |
| 434 | 421 |
| 435 void TextureImageTransportSurface::ReleaseTexture(int id) { | 422 void TextureImageTransportSurface::ReleaseTexture(int id) { |
| 436 if (!parent_stub_) | 423 if (!textures_[id].service_id) |
| 437 return; | 424 return; |
| 438 Texture& texture = textures_[id]; | 425 textures_[id].service_id = 0; |
| 439 TextureInfo* info = texture.info; | |
| 440 DCHECK(info); | |
| 441 | |
| 442 GLuint service_id = info->service_id(); | |
| 443 if (!service_id) | |
| 444 return; | |
| 445 info->SetServiceId(0); | |
| 446 | 426 |
| 447 { | 427 { |
| 448 content::ScopedFrameBufferBinder fbo_binder(fbo_id_); | 428 content::ScopedFrameBufferBinder fbo_binder(fbo_id_); |
| 449 glDeleteTextures(1, &service_id); | 429 glDeleteTextures(1, &textures_[id].service_id); |
| 450 } | 430 } |
| 451 glFlush(); | 431 glFlush(); |
| 452 CHECK_GL_ERROR(); | 432 CHECK_GL_ERROR(); |
| 453 } | 433 } |
| 454 | 434 |
| 455 void TextureImageTransportSurface::CreateBackTexture(const gfx::Size& size) { | 435 void TextureImageTransportSurface::CreateBackTexture(const gfx::Size& size) { |
| 456 if (!parent_stub_) | |
| 457 return; | |
| 458 Texture& texture = textures_[back()]; | 436 Texture& texture = textures_[back()]; |
| 459 TextureInfo* info = texture.info; | |
| 460 DCHECK(info); | |
| 461 | 437 |
| 462 GLuint service_id = info->service_id(); | 438 if (texture.service_id && texture.size == size && texture.sent_to_client) |
| 463 | |
| 464 if (service_id && texture.size == size && texture.sent_to_client) | |
| 465 return; | 439 return; |
| 466 | 440 |
| 467 if (!service_id) { | 441 if (!texture.service_id) { |
| 468 glGenTextures(1, &service_id); | 442 glGenTextures(1, &texture.service_id); |
| 469 info->SetServiceId(service_id); | |
| 470 } | 443 } |
| 471 | 444 |
| 472 if (size != texture.size) { | 445 if (size != texture.size) { |
| 473 texture.size = size; | 446 texture.size = size; |
| 474 TextureManager* texture_manager = | |
| 475 parent_stub_->decoder()->GetContextGroup()->texture_manager(); | |
| 476 texture_manager->SetLevelInfo( | |
| 477 info, | |
| 478 GL_TEXTURE_2D, | |
| 479 0, | |
| 480 GL_RGBA, | |
| 481 size.width(), | |
| 482 size.height(), | |
| 483 1, | |
| 484 0, | |
| 485 GL_RGBA, | |
| 486 GL_UNSIGNED_BYTE, | |
| 487 true); | |
| 488 } | 447 } |
| 489 | 448 |
| 490 { | 449 { |
| 491 content::ScopedTextureBinder texture_binder(service_id); | 450 content::ScopedTextureBinder texture_binder(texture.service_id); |
| 492 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | 451 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
| 493 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | 452 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
| 494 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 453 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
| 495 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 454 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
| 496 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, | 455 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, |
| 497 size.width(), size.height(), 0, | 456 size.width(), size.height(), 0, |
| 498 GL_RGBA, GL_UNSIGNED_BYTE, NULL); | 457 GL_RGBA, GL_UNSIGNED_BYTE, NULL); |
| 499 CHECK_GL_ERROR(); | 458 CHECK_GL_ERROR(); |
| 500 } | 459 } |
| 501 | 460 |
| 502 AttachBackTextureToFBO(); | 461 AttachBackTextureToFBO(); |
| 503 | 462 |
| 463 if (!texture.identifier) | |
| 464 texture.identifier = GenerateId(); | |
| 465 | |
| 504 GpuHostMsg_AcceleratedSurfaceNew_Params params; | 466 GpuHostMsg_AcceleratedSurfaceNew_Params params; |
| 505 params.width = size.width(); | 467 params.width = size.width(); |
| 506 params.height = size.height(); | 468 params.height = size.height(); |
| 507 params.surface_handle = texture.client_id; | 469 MailboxManager* manager = helper_->stub()->decoder()->GetContextGroup()-> |
| 470 mailbox_manager(); | |
| 471 gpu::gles2::MailboxName& name = texture.mailbox_name; | |
| 472 manager->GenerateMailboxName(&name); | |
| 473 params.mailbox_name.append((char*)name.key, sizeof(name.key)); | |
| 474 params.mailbox_name.append((char*)name.signature, sizeof(name.signature)); | |
| 475 params.surface_handle = texture.identifier; | |
| 508 helper_->SendAcceleratedSurfaceNew(params); | 476 helper_->SendAcceleratedSurfaceNew(params); |
| 509 texture.sent_to_client = true; | 477 texture.sent_to_client = true; |
| 510 } | 478 } |
| 511 | 479 |
| 512 void TextureImageTransportSurface::AttachBackTextureToFBO() { | 480 void TextureImageTransportSurface::AttachBackTextureToFBO() { |
| 513 if (!parent_stub_) | |
| 514 return; | |
| 515 TextureInfo* info = textures_[back()].info; | |
| 516 DCHECK(info); | |
| 517 | |
| 518 content::ScopedFrameBufferBinder fbo_binder(fbo_id_); | 481 content::ScopedFrameBufferBinder fbo_binder(fbo_id_); |
| 519 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, | 482 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, |
| 520 GL_COLOR_ATTACHMENT0, | 483 GL_COLOR_ATTACHMENT0, |
| 521 GL_TEXTURE_2D, | 484 GL_TEXTURE_2D, |
| 522 info->service_id(), | 485 textures_[back()].service_id, |
| 523 0); | 486 0); |
| 524 glFlush(); | 487 glFlush(); |
| 525 CHECK_GL_ERROR(); | 488 CHECK_GL_ERROR(); |
| 526 | 489 |
| 527 #ifndef NDEBUG | 490 #ifndef NDEBUG |
| 528 GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); | 491 GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); |
| 529 if (status != GL_FRAMEBUFFER_COMPLETE) { | 492 if (status != GL_FRAMEBUFFER_COMPLETE) { |
| 530 DLOG(ERROR) << "Framebuffer incomplete."; | 493 DLOG(ERROR) << "Framebuffer incomplete: " << status; |
| 494 DCHECK(false); | |
| 531 } | 495 } |
| 532 #endif | 496 #endif |
| 533 } | 497 } |
| 534 | 498 |
| 535 void TextureImageTransportSurface::ReleaseParentStub() { | 499 void TextureImageTransportSurface::ConsumeTexture(Texture& texture) { |
| 536 DCHECK(parent_stub_); | 500 MailboxManager* manager = helper_->stub()->decoder()->GetContextGroup()-> |
| 537 parent_stub_->RemoveDestructionObserver(this); | 501 mailbox_manager(); |
| 538 for (int i = 0; i < 2; ++i) { | 502 scoped_ptr<TextureDefinition> definition(manager->ConsumeTexture( |
| 539 Texture& texture = textures_[i]; | 503 GL_TEXTURE_2D, texture.mailbox_name)); |
| 540 texture.info = NULL; | 504 if (definition.get()) |
| 541 if (!texture.sent_to_client) | 505 texture.service_id = definition->ReleaseServiceId(); |
| 542 continue; | 506 |
| 543 GpuHostMsg_AcceleratedSurfaceRelease_Params params; | 507 // TODO: This can happen if the other side did not put the texture back |
| 544 params.identifier = texture.client_id; | 508 // before the sync point, or that other context was lost. |
| 545 helper_->SendAcceleratedSurfaceRelease(params); | 509 DCHECK(definition.get()); |
| 546 } | |
| 547 parent_stub_ = NULL; | |
| 548 } | 510 } |
| 511 | |
| 512 void TextureImageTransportSurface::ProduceTexture(Texture& texture) { | |
| 513 TextureManager* texture_manager = | |
| 514 helper_->stub()->decoder()->GetContextGroup()->texture_manager(); | |
| 515 MailboxManager* mailbox_manager = | |
| 516 helper_->stub()->decoder()->GetContextGroup()->mailbox_manager(); | |
| 517 DCHECK(texture.size.width() > 0 && texture.size.height() > 0); | |
| 518 TextureDefinition::LevelInfo info( | |
| 519 GL_TEXTURE_2D, GL_RGBA, texture.size.width(), texture.size.height(), 1, | |
| 520 0, GL_RGBA, GL_UNSIGNED_BYTE, true); | |
| 521 | |
| 522 TextureDefinition::LevelInfos level_infos; | |
| 523 level_infos.resize(1); | |
| 524 level_infos[0].resize(texture_manager->MaxLevelsForTarget(GL_TEXTURE_2D)); | |
| 525 level_infos[0][0] = info; | |
| 526 scoped_ptr<TextureDefinition> definition(new TextureDefinition( | |
| 527 GL_TEXTURE_2D, | |
| 528 texture.service_id, | |
| 529 true, | |
| 530 level_infos)); | |
| 531 mailbox_manager->ProduceTexture( | |
| 532 GL_TEXTURE_2D, | |
| 533 texture.mailbox_name, | |
| 534 definition.release(), | |
| 535 helper_->stub()->decoder()->GetContextGroup()->texture_manager()); | |
| 536 texture.service_id = 0; | |
| 537 } | |
| OLD | NEW |