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

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: Major simplification! 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),
72 handle_(handle), 73 handle_(handle),
73 parent_stub_(NULL) { 74 parent_stub_(NULL) {
74 helper_.reset(new ImageTransportHelper(this, 75 helper_.reset(new ImageTransportHelper(this,
75 manager, 76 manager,
76 stub, 77 stub,
77 gfx::kNullPluginWindow)); 78 gfx::kNullPluginWindow));
78 79
79 stub->AddDestructionObserver(this); 80 stub->AddDestructionObserver(this);
80 } 81 }
81 82
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
175 } 176 }
176 177
177 void TextureImageTransportSurface::SetBackbufferAllocation(bool allocation) { 178 void TextureImageTransportSurface::SetBackbufferAllocation(bool allocation) {
178 if (backbuffer_suggested_allocation_ == allocation) 179 if (backbuffer_suggested_allocation_ == allocation)
179 return; 180 return;
180 backbuffer_suggested_allocation_ = allocation; 181 backbuffer_suggested_allocation_ = allocation;
181 182
182 if (!helper_->MakeCurrent()) 183 if (!helper_->MakeCurrent())
183 return; 184 return;
184 185
185 if (backbuffer_suggested_allocation_) 186 if (backbuffer_suggested_allocation_) {
187 DCHECK(!textures_[back()].info->service_id() ||
188 !textures_[back()].sent_to_client);
186 CreateBackTexture(textures_[back()].size); 189 CreateBackTexture(textures_[back()].size);
187 else 190 } else {
188 ReleaseBackTexture(); 191 ReleaseTexture(back());
192 }
189 } 193 }
190 194
191 void TextureImageTransportSurface::SetFrontbufferAllocation(bool allocation) { 195 void TextureImageTransportSurface::SetFrontbufferAllocation(bool allocation) {
192 if (frontbuffer_suggested_allocation_ == allocation) 196 if (frontbuffer_suggested_allocation_ == allocation)
193 return; 197 return;
194 frontbuffer_suggested_allocation_ = allocation; 198 frontbuffer_suggested_allocation_ = allocation;
199 AdjustFrontBufferAllocation();
200 }
201
202 void TextureImageTransportSurface::AdjustFrontBufferAllocation() {
203 if (!helper_->MakeCurrent())
204 return;
205
206 if (!frontbuffer_suggested_allocation_ && !frontbuffer_is_protected_ &&
207 textures_[front()].info->service_id()) {
208 ReleaseTexture(front());
209 if (textures_[front()].sent_to_client) {
210 GpuHostMsg_AcceleratedSurfaceRelease_Params params;
211 params.identifier = textures_[front()].client_id;
212 helper_->SendAcceleratedSurfaceRelease(params);
213 textures_[front()].sent_to_client = false;
214 }
215 }
195 } 216 }
196 217
197 void* TextureImageTransportSurface::GetShareHandle() { 218 void* TextureImageTransportSurface::GetShareHandle() {
198 return GetHandle(); 219 return GetHandle();
199 } 220 }
200 221
201 void* TextureImageTransportSurface::GetDisplay() { 222 void* TextureImageTransportSurface::GetDisplay() {
202 return parent_stub_ ? parent_stub_->surface()->GetDisplay() : NULL; 223 return parent_stub_ ? parent_stub_->surface()->GetDisplay() : NULL;
203 } 224 }
204 225
(...skipping 20 matching lines...) Expand all
225 CHECK_GL_ERROR(); 246 CHECK_GL_ERROR();
226 fbo_id_ = 0; 247 fbo_id_ = 0;
227 } 248 }
228 249
229 stub_destroyed_ = true; 250 stub_destroyed_ = true;
230 } 251 }
231 } 252 }
232 253
233 bool TextureImageTransportSurface::SwapBuffers() { 254 bool TextureImageTransportSurface::SwapBuffers() {
234 DCHECK(backbuffer_suggested_allocation_); 255 DCHECK(backbuffer_suggested_allocation_);
235 if (!frontbuffer_suggested_allocation_) 256 if (!frontbuffer_suggested_allocation_ || !frontbuffer_is_protected_)
236 return true; 257 return true;
237 if (!parent_stub_) { 258 if (!parent_stub_) {
238 LOG(ERROR) << "SwapBuffers failed because no parent stub."; 259 LOG(ERROR) << "SwapBuffers failed because no parent stub.";
239 return false; 260 return false;
240 } 261 }
241 262
242 glFlush(); 263 glFlush();
243 front_ = back(); 264 front_ = back();
244 previous_damage_rect_ = gfx::Rect(textures_[front_].size); 265 previous_damage_rect_ = gfx::Rect(textures_[front()].size);
245 266
246 DCHECK(textures_[front_].client_id != 0); 267 DCHECK(textures_[front()].client_id != 0);
247 268
248 GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params; 269 GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params;
249 params.surface_handle = textures_[front_].client_id; 270 params.surface_handle = textures_[front()].client_id;
250 helper_->SendAcceleratedSurfaceBuffersSwapped(params); 271 helper_->SendAcceleratedSurfaceBuffersSwapped(params);
251 helper_->SetScheduled(false); 272 helper_->SetScheduled(false);
252 return true; 273 return true;
253 } 274 }
254 275
255 bool TextureImageTransportSurface::PostSubBuffer( 276 bool TextureImageTransportSurface::PostSubBuffer(
256 int x, int y, int width, int height) { 277 int x, int y, int width, int height) {
257 DCHECK(backbuffer_suggested_allocation_); 278 DCHECK(backbuffer_suggested_allocation_);
258 if (!frontbuffer_suggested_allocation_) 279 DCHECK(textures_[back()].info->service_id());
280 if (!frontbuffer_suggested_allocation_ || !frontbuffer_is_protected_)
259 return true; 281 return true;
260 // If we are recreating the frontbuffer with this swap, make sure we are 282 // If we are recreating the frontbuffer with this swap, make sure we are
261 // drawing a full frame. 283 // drawing a full frame.
262 DCHECK(textures_[front_].info->service_id() || 284 DCHECK(textures_[front()].info->service_id() ||
263 (!x && !y && gfx::Size(width, height) == textures_[back()].size)); 285 (!x && !y && gfx::Size(width, height) == textures_[back()].size));
264 if (!parent_stub_) { 286 if (!parent_stub_) {
265 LOG(ERROR) << "PostSubBuffer failed because no parent stub."; 287 LOG(ERROR) << "PostSubBuffer failed because no parent stub.";
266 return false; 288 return false;
267 } 289 }
268 290
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); 291 const gfx::Rect new_damage_rect(x, y, width, height);
279 292
280 // An empty damage rect is a successful no-op. 293 // An empty damage rect is a successful no-op.
281 if (new_damage_rect.IsEmpty()) 294 if (new_damage_rect.IsEmpty())
282 return true; 295 return true;
283 296
297 int back_texture_service_id = textures_[back()].info->service_id();
298 int front_texture_service_id = textures_[front()].info->service_id();
299
300 gfx::Size expected_size = textures_[back()].size;
301 bool surfaces_same_size = textures_[front()].size == expected_size;
302
284 if (surfaces_same_size) { 303 if (surfaces_same_size) {
285 std::vector<gfx::Rect> regions_to_copy; 304 std::vector<gfx::Rect> regions_to_copy;
286 GetRegionsToCopy(previous_damage_rect_, new_damage_rect, &regions_to_copy); 305 GetRegionsToCopy(previous_damage_rect_, new_damage_rect, &regions_to_copy);
287 306
288 ScopedFrameBufferBinder fbo_binder(fbo_id_); 307 ScopedFrameBufferBinder fbo_binder(fbo_id_);
289 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, 308 glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
290 GL_COLOR_ATTACHMENT0, 309 GL_COLOR_ATTACHMENT0,
291 GL_TEXTURE_2D, 310 GL_TEXTURE_2D,
292 front_texture_service_id, 311 front_texture_service_id,
293 0); 312 0);
294 ScopedTextureBinder texture_binder(back_texture_service_id); 313 ScopedTextureBinder texture_binder(back_texture_service_id);
295 314
296 for (size_t i = 0; i < regions_to_copy.size(); ++i) { 315 for (size_t i = 0; i < regions_to_copy.size(); ++i) {
297 const gfx::Rect& region_to_copy = regions_to_copy[i]; 316 const gfx::Rect& region_to_copy = regions_to_copy[i];
298 if (!region_to_copy.IsEmpty()) { 317 if (!region_to_copy.IsEmpty()) {
299 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, region_to_copy.x(), 318 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, region_to_copy.x(),
300 region_to_copy.y(), region_to_copy.x(), region_to_copy.y(), 319 region_to_copy.y(), region_to_copy.x(), region_to_copy.y(),
301 region_to_copy.width(), region_to_copy.height()); 320 region_to_copy.width(), region_to_copy.height());
302 } 321 }
303 } 322 }
304 } else { 323 } else {
305 DCHECK(new_damage_rect == gfx::Rect(expected_size)); 324 DCHECK(new_damage_rect == gfx::Rect(expected_size));
306 } 325 }
307 326
308 glFlush(); 327 glFlush();
309 front_ = back(); 328 front_ = back();
329 previous_damage_rect_ = new_damage_rect;
330
331 DCHECK(textures_[front()].client_id);
310 332
311 GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params params; 333 GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params params;
312 params.surface_handle = textures_[front_].client_id; 334 params.surface_handle = textures_[front()].client_id;
313 params.x = x; 335 params.x = x;
314 params.y = y; 336 params.y = y;
315 params.width = width; 337 params.width = width;
316 params.height = height; 338 params.height = height;
317 helper_->SendAcceleratedSurfacePostSubBuffer(params); 339 helper_->SendAcceleratedSurfacePostSubBuffer(params);
318 helper_->SetScheduled(false); 340 helper_->SetScheduled(false);
319
320 previous_damage_rect_ = new_damage_rect;
321 return true; 341 return true;
322 } 342 }
323 343
324 std::string TextureImageTransportSurface::GetExtensions() { 344 std::string TextureImageTransportSurface::GetExtensions() {
325 std::string extensions = gfx::GLSurface::GetExtensions(); 345 std::string extensions = gfx::GLSurface::GetExtensions();
326 extensions += extensions.empty() ? "" : " "; 346 extensions += extensions.empty() ? "" : " ";
327 extensions += "GL_CHROMIUM_front_buffer_cached "; 347 extensions += "GL_CHROMIUM_front_buffer_cached ";
328 extensions += "GL_CHROMIUM_post_sub_buffer"; 348 extensions += "GL_CHROMIUM_post_sub_buffer";
329 return extensions; 349 return extensions;
330 } 350 }
331 351
332 gfx::Size TextureImageTransportSurface::GetSize() { 352 gfx::Size TextureImageTransportSurface::GetSize() {
333 return textures_[back()].size; 353 return textures_[back()].size;
334 } 354 }
335 355
336 void* TextureImageTransportSurface::GetHandle() { 356 void* TextureImageTransportSurface::GetHandle() {
337 return parent_stub_ ? parent_stub_->surface()->GetHandle() : NULL; 357 return parent_stub_ ? parent_stub_->surface()->GetHandle() : NULL;
338 } 358 }
339 359
340 360
341 void TextureImageTransportSurface::OnNewSurfaceACK( 361 void TextureImageTransportSurface::OnNewSurfaceACK(
342 uint64 surface_handle, TransportDIB::Handle /*shm_handle*/) { 362 uint64 surface_handle, TransportDIB::Handle /*shm_handle*/) {
343 } 363 }
344 364
365 void TextureImageTransportSurface::OnSetFrontSurfaceIsProtected(
366 bool is_protected) {
367 if (frontbuffer_is_protected_ == is_protected)
368 return;
369 frontbuffer_is_protected_ = is_protected;
370 AdjustFrontBufferAllocation();
371
372 // If surface is set to protected, and we haven't actually released it yet,
373 // we can set the ui surface handle now just by sending a swap message.
374 if (is_protected && textures_[front()].info->service_id() &&
375 textures_[front()].sent_to_client) {
376 // TODO: safe to send swapbuffers when using postsubbuffers usually?
piman 2012/06/11 21:32:24 Yes, it's always safe. A Swap is essentially a Pos
mmocny 2012/06/12 18:26:18 Done.
377 GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params;
378 params.surface_handle = textures_[front()].client_id;
379 helper_->SendAcceleratedSurfaceBuffersSwapped(params);
380 // TODO: can we do this without descheduling the channel?
381 helper_->SetScheduled(false);
382 }
383 }
384
345 void TextureImageTransportSurface::OnBuffersSwappedACK() { 385 void TextureImageTransportSurface::OnBuffersSwappedACK() {
346 if (helper_->MakeCurrent()) { 386 if (helper_->MakeCurrent()) {
347 if (textures_[front_].size != textures_[back()].size) { 387 if (textures_[front()].size != textures_[back()].size ||
piman 2012/06/11 21:32:24 We should be very careful here. When restoring th
mmocny 2012/06/11 21:45:09 Okay, this sounds like it could be potentially hai
mmocny 2012/06/12 18:26:18 I got around this issue, as well as having other b
348 CreateBackTexture(textures_[front_].size); 388 !textures_[back()].info->service_id() ||
389 !textures_[back()].sent_to_client) {
390 // We may get an ACK from a stale swap just to reschedule. In that case,
391 // we may not have a backbuffer suggestion and should not recreate one.
392 if (backbuffer_suggested_allocation_)
393 CreateBackTexture(textures_[front()].size);
349 } else { 394 } else {
350 AttachBackTextureToFBO(); 395 AttachBackTextureToFBO();
351 } 396 }
352 } 397 }
353 398
354 // Even if MakeCurrent fails, schedule anyway, to trigger the lost context 399 // Even if MakeCurrent fails, schedule anyway, to trigger the lost context
355 // logic. 400 // logic.
356 helper_->SetScheduled(true); 401 helper_->SetScheduled(true);
357 } 402 }
358 403
359 void TextureImageTransportSurface::OnPostSubBufferACK() { 404 void TextureImageTransportSurface::OnPostSubBufferACK() {
360 OnBuffersSwappedACK(); 405 OnBuffersSwappedACK();
361 } 406 }
362 407
363 void TextureImageTransportSurface::OnResizeViewACK() { 408 void TextureImageTransportSurface::OnResizeViewACK() {
364 NOTREACHED(); 409 NOTREACHED();
365 } 410 }
366 411
367 void TextureImageTransportSurface::ReleaseBackTexture() { 412 void TextureImageTransportSurface::ReleaseTexture(int id) {
368 if (!parent_stub_) 413 if (!parent_stub_)
369 return; 414 return;
370 TextureInfo* info = textures_[back()].info; 415 Texture& texture = textures_[id];
416 TextureInfo* info = texture.info;
371 DCHECK(info); 417 DCHECK(info);
372 418
373 GLuint service_id = info->service_id(); 419 GLuint service_id = info->service_id();
374 if (!service_id) 420 if (!service_id)
375 return; 421 return;
376 info->SetServiceId(0); 422 info->SetServiceId(0);
377 423
378 { 424 {
379 ScopedFrameBufferBinder fbo_binder(fbo_id_); 425 ScopedFrameBufferBinder fbo_binder(fbo_id_);
380 glDeleteTextures(1, &service_id); 426 glDeleteTextures(1, &service_id);
381 } 427 }
382 glFlush(); 428 glFlush();
383 CHECK_GL_ERROR(); 429 CHECK_GL_ERROR();
384 } 430 }
385 431
386 void TextureImageTransportSurface::CreateBackTexture(const gfx::Size& size) { 432 void TextureImageTransportSurface::CreateBackTexture(const gfx::Size& size) {
387 if (!parent_stub_) 433 if (!parent_stub_)
388 return; 434 return;
389 Texture& texture = textures_[back()]; 435 Texture& texture = textures_[back()];
390 TextureInfo* info = texture.info; 436 TextureInfo* info = texture.info;
391 DCHECK(info); 437 DCHECK(info);
392 438
393 GLuint service_id = info->service_id(); 439 GLuint service_id = info->service_id();
394 440
395 if (service_id && texture.size == size) 441 if (service_id && texture.size == size && texture.sent_to_client)
396 return; 442 return;
397 443
398 if (!service_id) { 444 if (!service_id) {
399 glGenTextures(1, &service_id); 445 glGenTextures(1, &service_id);
400 info->SetServiceId(service_id); 446 info->SetServiceId(service_id);
401 } 447 }
402 448
403 if (size != texture.size) { 449 if (size != texture.size) {
404 texture.size = size; 450 texture.size = size;
405 TextureManager* texture_manager = 451 TextureManager* texture_manager =
(...skipping 30 matching lines...) Expand all
436 params.width = size.width(); 482 params.width = size.width();
437 params.height = size.height(); 483 params.height = size.height();
438 params.surface_handle = texture.client_id; 484 params.surface_handle = texture.client_id;
439 helper_->SendAcceleratedSurfaceNew(params); 485 helper_->SendAcceleratedSurfaceNew(params);
440 texture.sent_to_client = true; 486 texture.sent_to_client = true;
441 } 487 }
442 488
443 void TextureImageTransportSurface::AttachBackTextureToFBO() { 489 void TextureImageTransportSurface::AttachBackTextureToFBO() {
444 if (!parent_stub_) 490 if (!parent_stub_)
445 return; 491 return;
446 DCHECK(textures_[back()].info); 492 TextureInfo* info = textures_[back()].info;
493 DCHECK(info);
447 494
448 ScopedFrameBufferBinder fbo_binder(fbo_id_); 495 ScopedFrameBufferBinder fbo_binder(fbo_id_);
449 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, 496 glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
450 GL_COLOR_ATTACHMENT0, 497 GL_COLOR_ATTACHMENT0,
451 GL_TEXTURE_2D, 498 GL_TEXTURE_2D,
452 textures_[back()].info->service_id(), 499 info->service_id(),
453 0); 500 0);
454 glFlush(); 501 glFlush();
455 CHECK_GL_ERROR(); 502 CHECK_GL_ERROR();
456 503
457 #ifndef NDEBUG 504 #ifndef NDEBUG
458 GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); 505 GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
459 if (status != GL_FRAMEBUFFER_COMPLETE) { 506 if (status != GL_FRAMEBUFFER_COMPLETE) {
460 DLOG(ERROR) << "Framebuffer incomplete."; 507 DLOG(ERROR) << "Framebuffer incomplete.";
461 } 508 }
462 #endif 509 #endif
463 } 510 }
464 511
465 void TextureImageTransportSurface::ReleaseParentStub() { 512 void TextureImageTransportSurface::ReleaseParentStub() {
466 DCHECK(parent_stub_); 513 DCHECK(parent_stub_);
467 parent_stub_->RemoveDestructionObserver(this); 514 parent_stub_->RemoveDestructionObserver(this);
468 for (int i = 0; i < 2; ++i) { 515 for (int i = 0; i < 2; ++i) {
469 Texture& texture = textures_[i]; 516 Texture& texture = textures_[i];
470 texture.info = NULL; 517 texture.info = NULL;
471 if (!texture.sent_to_client) 518 if (!texture.sent_to_client)
472 continue; 519 continue;
473 GpuHostMsg_AcceleratedSurfaceRelease_Params params; 520 GpuHostMsg_AcceleratedSurfaceRelease_Params params;
474 params.identifier = texture.client_id; 521 params.identifier = texture.client_id;
475 helper_->SendAcceleratedSurfaceRelease(params); 522 helper_->SendAcceleratedSurfaceRelease(params);
476 } 523 }
477 parent_stub_ = NULL; 524 parent_stub_ = NULL;
478 } 525 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698