Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(224)

Side by Side Diff: content/common/gpu/texture_image_transport_surface.cc

Issue 10052018: Drop frontbuffers with ui-use-gpu-process, synchronized with browser, decoupled from backbuffer dro… (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 "base/command_line.h" 7 #include "base/command_line.h"
8 #include "content/common/gpu/gpu_channel.h" 8 #include "content/common/gpu/gpu_channel.h"
9 #include "content/common/gpu/gpu_channel_manager.h" 9 #include "content/common/gpu/gpu_channel_manager.h"
10 #include "content/common/gpu/gpu_messages.h" 10 #include "content/common/gpu/gpu_messages.h"
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
62 62
63 TextureImageTransportSurface::TextureImageTransportSurface( 63 TextureImageTransportSurface::TextureImageTransportSurface(
64 GpuChannelManager* manager, 64 GpuChannelManager* manager,
65 GpuCommandBufferStub* stub, 65 GpuCommandBufferStub* stub,
66 const gfx::GLSurfaceHandle& handle) 66 const gfx::GLSurfaceHandle& handle)
67 : fbo_id_(0), 67 : fbo_id_(0),
68 front_(0), 68 front_(0),
69 stub_destroyed_(false), 69 stub_destroyed_(false),
70 backbuffer_suggested_allocation_(true), 70 backbuffer_suggested_allocation_(true),
71 frontbuffer_suggested_allocation_(true), 71 frontbuffer_suggested_allocation_(true),
72 frontbuffer_is_protected_(true),
73 protection_state_id_(0),
72 handle_(handle), 74 handle_(handle),
73 parent_stub_(NULL) { 75 parent_stub_(NULL) {
74 helper_.reset(new ImageTransportHelper(this, 76 helper_.reset(new ImageTransportHelper(this,
75 manager, 77 manager,
76 stub, 78 stub,
77 gfx::kNullPluginWindow)); 79 gfx::kNullPluginWindow));
78 80
79 stub->AddDestructionObserver(this); 81 stub->AddDestructionObserver(this);
80 } 82 }
81 83
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
175 } 177 }
176 178
177 void TextureImageTransportSurface::SetBackbufferAllocation(bool allocation) { 179 void TextureImageTransportSurface::SetBackbufferAllocation(bool allocation) {
178 if (backbuffer_suggested_allocation_ == allocation) 180 if (backbuffer_suggested_allocation_ == allocation)
179 return; 181 return;
180 backbuffer_suggested_allocation_ = allocation; 182 backbuffer_suggested_allocation_ = allocation;
181 183
182 if (!helper_->MakeCurrent()) 184 if (!helper_->MakeCurrent())
183 return; 185 return;
184 186
185 if (backbuffer_suggested_allocation_) 187 if (backbuffer_suggested_allocation_) {
188 DCHECK(!textures_[back()].info->service_id() ||
189 !textures_[back()].sent_to_client);
186 CreateBackTexture(textures_[back()].size); 190 CreateBackTexture(textures_[back()].size);
187 else 191 } else {
188 ReleaseBackTexture(); 192 ReleaseTexture(back());
193 }
189 } 194 }
190 195
191 void TextureImageTransportSurface::SetFrontbufferAllocation(bool allocation) { 196 void TextureImageTransportSurface::SetFrontbufferAllocation(bool allocation) {
192 if (frontbuffer_suggested_allocation_ == allocation) 197 if (frontbuffer_suggested_allocation_ == allocation)
193 return; 198 return;
194 frontbuffer_suggested_allocation_ = allocation; 199 frontbuffer_suggested_allocation_ = allocation;
200 AdjustFrontBufferAllocation();
201 }
202
203 void TextureImageTransportSurface::AdjustFrontBufferAllocation() {
204 if (!helper_->MakeCurrent())
205 return;
206
207 if (!frontbuffer_suggested_allocation_ && !frontbuffer_is_protected_ &&
208 textures_[front()].info->service_id()) {
209 ReleaseTexture(front());
210 if (textures_[front()].sent_to_client) {
211 GpuHostMsg_AcceleratedSurfaceRelease_Params params;
212 params.identifier = textures_[front()].client_id;
213 helper_->SendAcceleratedSurfaceRelease(params);
214 textures_[front()].sent_to_client = false;
215 }
216 }
195 } 217 }
196 218
197 void* TextureImageTransportSurface::GetShareHandle() { 219 void* TextureImageTransportSurface::GetShareHandle() {
198 return GetHandle(); 220 return GetHandle();
199 } 221 }
200 222
201 void* TextureImageTransportSurface::GetDisplay() { 223 void* TextureImageTransportSurface::GetDisplay() {
202 return parent_stub_ ? parent_stub_->surface()->GetDisplay() : NULL; 224 return parent_stub_ ? parent_stub_->surface()->GetDisplay() : NULL;
203 } 225 }
204 226
(...skipping 20 matching lines...) Expand all
225 CHECK_GL_ERROR(); 247 CHECK_GL_ERROR();
226 fbo_id_ = 0; 248 fbo_id_ = 0;
227 } 249 }
228 250
229 stub_destroyed_ = true; 251 stub_destroyed_ = true;
230 } 252 }
231 } 253 }
232 254
233 bool TextureImageTransportSurface::SwapBuffers() { 255 bool TextureImageTransportSurface::SwapBuffers() {
234 DCHECK(backbuffer_suggested_allocation_); 256 DCHECK(backbuffer_suggested_allocation_);
235 if (!frontbuffer_suggested_allocation_) 257 if (!frontbuffer_suggested_allocation_ || !frontbuffer_is_protected_)
236 return true; 258 return true;
237 if (!parent_stub_) { 259 if (!parent_stub_) {
238 LOG(ERROR) << "SwapBuffers failed because no parent stub."; 260 LOG(ERROR) << "SwapBuffers failed because no parent stub.";
239 return false; 261 return false;
240 } 262 }
241 263
242 glFlush(); 264 glFlush();
243 front_ = back(); 265 front_ = back();
244 previous_damage_rect_ = gfx::Rect(textures_[front_].size); 266 previous_damage_rect_ = gfx::Rect(textures_[front()].size);
245 267
246 DCHECK(textures_[front_].client_id != 0); 268 DCHECK(textures_[front()].client_id != 0);
247 269
248 GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params; 270 GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params;
249 params.surface_handle = textures_[front_].client_id; 271 params.surface_handle = textures_[front()].client_id;
272 #if defined(USE_AURA)
273 params.protection_state_id = protection_state_id_;
274 params.require_ack = true;
275 #endif
250 helper_->SendAcceleratedSurfaceBuffersSwapped(params); 276 helper_->SendAcceleratedSurfaceBuffersSwapped(params);
251 helper_->SetScheduled(false); 277 helper_->SetScheduled(false);
252 return true; 278 return true;
253 } 279 }
254 280
255 bool TextureImageTransportSurface::PostSubBuffer( 281 bool TextureImageTransportSurface::PostSubBuffer(
256 int x, int y, int width, int height) { 282 int x, int y, int width, int height) {
257 DCHECK(backbuffer_suggested_allocation_); 283 DCHECK(backbuffer_suggested_allocation_);
258 if (!frontbuffer_suggested_allocation_) 284 DCHECK(textures_[back()].info->service_id());
285 if (!frontbuffer_suggested_allocation_ || !frontbuffer_is_protected_)
259 return true; 286 return true;
260 // If we are recreating the frontbuffer with this swap, make sure we are 287 // If we are recreating the frontbuffer with this swap, make sure we are
261 // drawing a full frame. 288 // drawing a full frame.
262 DCHECK(textures_[front_].info->service_id() || 289 DCHECK(textures_[front()].info->service_id() ||
263 (!x && !y && gfx::Size(width, height) == textures_[back()].size)); 290 (!x && !y && gfx::Size(width, height) == textures_[back()].size));
264 if (!parent_stub_) { 291 if (!parent_stub_) {
265 LOG(ERROR) << "PostSubBuffer failed because no parent stub."; 292 LOG(ERROR) << "PostSubBuffer failed because no parent stub.";
266 return false; 293 return false;
267 } 294 }
268 295
269 DCHECK(textures_[back()].info);
270 int back_texture_service_id = textures_[back()].info->service_id();
271
272 DCHECK(textures_[front_].info);
273 int front_texture_service_id = textures_[front_].info->service_id();
274
275 gfx::Size expected_size = textures_[back()].size;
276 bool surfaces_same_size = textures_[front_].size == expected_size;
277
278 const gfx::Rect new_damage_rect(x, y, width, height); 296 const gfx::Rect new_damage_rect(x, y, width, height);
279 297
280 // An empty damage rect is a successful no-op. 298 // An empty damage rect is a successful no-op.
281 if (new_damage_rect.IsEmpty()) 299 if (new_damage_rect.IsEmpty())
282 return true; 300 return true;
283 301
302 int back_texture_service_id = textures_[back()].info->service_id();
303 int front_texture_service_id = textures_[front()].info->service_id();
304
305 gfx::Size expected_size = textures_[back()].size;
306 bool surfaces_same_size = textures_[front()].size == expected_size;
307
284 if (surfaces_same_size) { 308 if (surfaces_same_size) {
285 std::vector<gfx::Rect> regions_to_copy; 309 std::vector<gfx::Rect> regions_to_copy;
286 GetRegionsToCopy(previous_damage_rect_, new_damage_rect, &regions_to_copy); 310 GetRegionsToCopy(previous_damage_rect_, new_damage_rect, &regions_to_copy);
287 311
288 ScopedFrameBufferBinder fbo_binder(fbo_id_); 312 ScopedFrameBufferBinder fbo_binder(fbo_id_);
289 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, 313 glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
290 GL_COLOR_ATTACHMENT0, 314 GL_COLOR_ATTACHMENT0,
291 GL_TEXTURE_2D, 315 GL_TEXTURE_2D,
292 front_texture_service_id, 316 front_texture_service_id,
293 0); 317 0);
294 ScopedTextureBinder texture_binder(back_texture_service_id); 318 ScopedTextureBinder texture_binder(back_texture_service_id);
295 319
296 for (size_t i = 0; i < regions_to_copy.size(); ++i) { 320 for (size_t i = 0; i < regions_to_copy.size(); ++i) {
297 const gfx::Rect& region_to_copy = regions_to_copy[i]; 321 const gfx::Rect& region_to_copy = regions_to_copy[i];
298 if (!region_to_copy.IsEmpty()) { 322 if (!region_to_copy.IsEmpty()) {
299 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, region_to_copy.x(), 323 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, region_to_copy.x(),
300 region_to_copy.y(), region_to_copy.x(), region_to_copy.y(), 324 region_to_copy.y(), region_to_copy.x(), region_to_copy.y(),
301 region_to_copy.width(), region_to_copy.height()); 325 region_to_copy.width(), region_to_copy.height());
302 } 326 }
303 } 327 }
304 } else { 328 } else {
305 DCHECK(new_damage_rect == gfx::Rect(expected_size)); 329 DCHECK(new_damage_rect == gfx::Rect(expected_size));
306 } 330 }
307 331
308 glFlush(); 332 glFlush();
309 front_ = back(); 333 front_ = back();
334 previous_damage_rect_ = new_damage_rect;
335
336 DCHECK(textures_[front()].client_id);
310 337
311 GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params params; 338 GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params params;
312 params.surface_handle = textures_[front_].client_id; 339 params.surface_handle = textures_[front()].client_id;
313 params.x = x; 340 params.x = x;
314 params.y = y; 341 params.y = y;
315 params.width = width; 342 params.width = width;
316 params.height = height; 343 params.height = height;
344 #if defined(USE_AURA)
piman 2012/06/12 23:05:12 nit: somehow it feels wrong to have a #ifdef USE_A
345 params.protection_state_id = protection_state_id_;
346 #endif
317 helper_->SendAcceleratedSurfacePostSubBuffer(params); 347 helper_->SendAcceleratedSurfacePostSubBuffer(params);
318 helper_->SetScheduled(false); 348 helper_->SetScheduled(false);
319
320 previous_damage_rect_ = new_damage_rect;
321 return true; 349 return true;
322 } 350 }
323 351
324 std::string TextureImageTransportSurface::GetExtensions() { 352 std::string TextureImageTransportSurface::GetExtensions() {
325 std::string extensions = gfx::GLSurface::GetExtensions(); 353 std::string extensions = gfx::GLSurface::GetExtensions();
326 extensions += extensions.empty() ? "" : " "; 354 extensions += extensions.empty() ? "" : " ";
327 extensions += "GL_CHROMIUM_front_buffer_cached "; 355 extensions += "GL_CHROMIUM_front_buffer_cached ";
328 extensions += "GL_CHROMIUM_post_sub_buffer"; 356 extensions += "GL_CHROMIUM_post_sub_buffer";
329 return extensions; 357 return extensions;
330 } 358 }
331 359
332 gfx::Size TextureImageTransportSurface::GetSize() { 360 gfx::Size TextureImageTransportSurface::GetSize() {
333 return textures_[back()].size; 361 return textures_[back()].size;
334 } 362 }
335 363
336 void* TextureImageTransportSurface::GetHandle() { 364 void* TextureImageTransportSurface::GetHandle() {
337 return parent_stub_ ? parent_stub_->surface()->GetHandle() : NULL; 365 return parent_stub_ ? parent_stub_->surface()->GetHandle() : NULL;
338 } 366 }
339 367
340 368
341 void TextureImageTransportSurface::OnNewSurfaceACK( 369 void TextureImageTransportSurface::OnNewSurfaceACK(
342 uint64 surface_handle, TransportDIB::Handle /*shm_handle*/) { 370 uint64 surface_handle, TransportDIB::Handle /*shm_handle*/) {
343 } 371 }
344 372
373 void TextureImageTransportSurface::OnSetFrontSurfaceIsProtected(
374 bool is_protected, uint32 protection_state_id) {
375 protection_state_id_ = protection_state_id;
376 if (frontbuffer_is_protected_ == is_protected)
377 return;
378 frontbuffer_is_protected_ = is_protected;
379 AdjustFrontBufferAllocation();
380
381 // If surface is set to protected, and we haven't actually released it yet,
382 // we can set the ui surface handle now just by sending a swap message.
383 if (is_protected && textures_[front()].info->service_id() &&
384 textures_[front()].sent_to_client) {
385 GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params;
386 params.surface_handle = textures_[front()].client_id;
387 #if defined(USE_AURA)
388 params.protection_state_id = protection_state_id_;
389 params.require_ack = false;
390 #endif
391 helper_->SendAcceleratedSurfaceBuffersSwapped(params);
392 }
393 }
394
345 void TextureImageTransportSurface::OnBuffersSwappedACK() { 395 void TextureImageTransportSurface::OnBuffersSwappedACK() {
346 if (helper_->MakeCurrent()) { 396 if (helper_->MakeCurrent()) {
347 if (textures_[front_].size != textures_[back()].size) { 397 if (textures_[front()].size != textures_[back()].size ||
348 CreateBackTexture(textures_[front_].size); 398 !textures_[back()].info->service_id() ||
399 !textures_[back()].sent_to_client) {
400 // We may get an ACK from a stale swap just to reschedule. In that case,
401 // we may not have a backbuffer suggestion and should not recreate one.
402 if (backbuffer_suggested_allocation_)
403 CreateBackTexture(textures_[front()].size);
349 } else { 404 } else {
350 AttachBackTextureToFBO(); 405 AttachBackTextureToFBO();
351 } 406 }
352 } 407 }
353 408
354 // Even if MakeCurrent fails, schedule anyway, to trigger the lost context 409 // Even if MakeCurrent fails, schedule anyway, to trigger the lost context
355 // logic. 410 // logic.
356 helper_->SetScheduled(true); 411 helper_->SetScheduled(true);
357 } 412 }
358 413
359 void TextureImageTransportSurface::OnPostSubBufferACK() { 414 void TextureImageTransportSurface::OnPostSubBufferACK() {
360 OnBuffersSwappedACK(); 415 OnBuffersSwappedACK();
361 } 416 }
362 417
363 void TextureImageTransportSurface::OnResizeViewACK() { 418 void TextureImageTransportSurface::OnResizeViewACK() {
364 NOTREACHED(); 419 NOTREACHED();
365 } 420 }
366 421
367 void TextureImageTransportSurface::ReleaseBackTexture() { 422 void TextureImageTransportSurface::ReleaseTexture(int id) {
368 if (!parent_stub_) 423 if (!parent_stub_)
369 return; 424 return;
370 TextureInfo* info = textures_[back()].info; 425 Texture& texture = textures_[id];
426 TextureInfo* info = texture.info;
371 DCHECK(info); 427 DCHECK(info);
372 428
373 GLuint service_id = info->service_id(); 429 GLuint service_id = info->service_id();
374 if (!service_id) 430 if (!service_id)
375 return; 431 return;
376 info->SetServiceId(0); 432 info->SetServiceId(0);
377 433
378 { 434 {
379 ScopedFrameBufferBinder fbo_binder(fbo_id_); 435 ScopedFrameBufferBinder fbo_binder(fbo_id_);
380 glDeleteTextures(1, &service_id); 436 glDeleteTextures(1, &service_id);
381 } 437 }
382 glFlush(); 438 glFlush();
383 CHECK_GL_ERROR(); 439 CHECK_GL_ERROR();
384 } 440 }
385 441
386 void TextureImageTransportSurface::CreateBackTexture(const gfx::Size& size) { 442 void TextureImageTransportSurface::CreateBackTexture(const gfx::Size& size) {
387 if (!parent_stub_) 443 if (!parent_stub_)
388 return; 444 return;
389 Texture& texture = textures_[back()]; 445 Texture& texture = textures_[back()];
390 TextureInfo* info = texture.info; 446 TextureInfo* info = texture.info;
391 DCHECK(info); 447 DCHECK(info);
392 448
393 GLuint service_id = info->service_id(); 449 GLuint service_id = info->service_id();
394 450
395 if (service_id && texture.size == size) 451 if (service_id && texture.size == size && texture.sent_to_client)
396 return; 452 return;
397 453
398 if (!service_id) { 454 if (!service_id) {
399 glGenTextures(1, &service_id); 455 glGenTextures(1, &service_id);
400 info->SetServiceId(service_id); 456 info->SetServiceId(service_id);
401 } 457 }
402 458
403 if (size != texture.size) { 459 if (size != texture.size) {
404 texture.size = size; 460 texture.size = size;
405 TextureManager* texture_manager = 461 TextureManager* texture_manager =
(...skipping 30 matching lines...) Expand all
436 params.width = size.width(); 492 params.width = size.width();
437 params.height = size.height(); 493 params.height = size.height();
438 params.surface_handle = texture.client_id; 494 params.surface_handle = texture.client_id;
439 helper_->SendAcceleratedSurfaceNew(params); 495 helper_->SendAcceleratedSurfaceNew(params);
440 texture.sent_to_client = true; 496 texture.sent_to_client = true;
441 } 497 }
442 498
443 void TextureImageTransportSurface::AttachBackTextureToFBO() { 499 void TextureImageTransportSurface::AttachBackTextureToFBO() {
444 if (!parent_stub_) 500 if (!parent_stub_)
445 return; 501 return;
446 DCHECK(textures_[back()].info); 502 TextureInfo* info = textures_[back()].info;
503 DCHECK(info);
447 504
448 ScopedFrameBufferBinder fbo_binder(fbo_id_); 505 ScopedFrameBufferBinder fbo_binder(fbo_id_);
449 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, 506 glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
450 GL_COLOR_ATTACHMENT0, 507 GL_COLOR_ATTACHMENT0,
451 GL_TEXTURE_2D, 508 GL_TEXTURE_2D,
452 textures_[back()].info->service_id(), 509 info->service_id(),
453 0); 510 0);
454 glFlush(); 511 glFlush();
455 CHECK_GL_ERROR(); 512 CHECK_GL_ERROR();
456 513
457 #ifndef NDEBUG 514 #ifndef NDEBUG
458 GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); 515 GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
459 if (status != GL_FRAMEBUFFER_COMPLETE) { 516 if (status != GL_FRAMEBUFFER_COMPLETE) {
460 DLOG(ERROR) << "Framebuffer incomplete."; 517 DLOG(ERROR) << "Framebuffer incomplete.";
461 } 518 }
462 #endif 519 #endif
463 } 520 }
464 521
465 void TextureImageTransportSurface::ReleaseParentStub() { 522 void TextureImageTransportSurface::ReleaseParentStub() {
466 DCHECK(parent_stub_); 523 DCHECK(parent_stub_);
467 parent_stub_->RemoveDestructionObserver(this); 524 parent_stub_->RemoveDestructionObserver(this);
468 for (int i = 0; i < 2; ++i) { 525 for (int i = 0; i < 2; ++i) {
469 Texture& texture = textures_[i]; 526 Texture& texture = textures_[i];
470 texture.info = NULL; 527 texture.info = NULL;
471 if (!texture.sent_to_client) 528 if (!texture.sent_to_client)
472 continue; 529 continue;
473 GpuHostMsg_AcceleratedSurfaceRelease_Params params; 530 GpuHostMsg_AcceleratedSurfaceRelease_Params params;
474 params.identifier = texture.client_id; 531 params.identifier = texture.client_id;
475 helper_->SendAcceleratedSurfaceRelease(params); 532 helper_->SendAcceleratedSurfaceRelease(params);
476 } 533 }
477 parent_stub_ = NULL; 534 parent_stub_ = NULL;
478 } 535 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698