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

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: fix ALL the issues. 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 visibility_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 params.visibility_state_id = visibility_state_id_;
273 params.require_ack = true;
250 helper_->SendAcceleratedSurfaceBuffersSwapped(params); 274 helper_->SendAcceleratedSurfaceBuffersSwapped(params);
251 helper_->SetScheduled(false); 275 helper_->SetScheduled(false);
252 return true; 276 return true;
253 } 277 }
254 278
255 bool TextureImageTransportSurface::PostSubBuffer( 279 bool TextureImageTransportSurface::PostSubBuffer(
256 int x, int y, int width, int height) { 280 int x, int y, int width, int height) {
257 DCHECK(backbuffer_suggested_allocation_); 281 DCHECK(backbuffer_suggested_allocation_);
258 if (!frontbuffer_suggested_allocation_) 282 DCHECK(textures_[back()].info->service_id());
283 if (!frontbuffer_suggested_allocation_ || !frontbuffer_is_protected_)
259 return true; 284 return true;
260 // If we are recreating the frontbuffer with this swap, make sure we are 285 // If we are recreating the frontbuffer with this swap, make sure we are
261 // drawing a full frame. 286 // drawing a full frame.
262 DCHECK(textures_[front_].info->service_id() || 287 DCHECK(textures_[front()].info->service_id() ||
263 (!x && !y && gfx::Size(width, height) == textures_[back()].size)); 288 (!x && !y && gfx::Size(width, height) == textures_[back()].size));
264 if (!parent_stub_) { 289 if (!parent_stub_) {
265 LOG(ERROR) << "PostSubBuffer failed because no parent stub."; 290 LOG(ERROR) << "PostSubBuffer failed because no parent stub.";
266 return false; 291 return false;
267 } 292 }
268 293
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); 294 const gfx::Rect new_damage_rect(x, y, width, height);
279 295
280 // An empty damage rect is a successful no-op. 296 // An empty damage rect is a successful no-op.
281 if (new_damage_rect.IsEmpty()) 297 if (new_damage_rect.IsEmpty())
282 return true; 298 return true;
283 299
300 int back_texture_service_id = textures_[back()].info->service_id();
301 int front_texture_service_id = textures_[front()].info->service_id();
302
303 gfx::Size expected_size = textures_[back()].size;
304 bool surfaces_same_size = textures_[front()].size == expected_size;
305
284 if (surfaces_same_size) { 306 if (surfaces_same_size) {
285 std::vector<gfx::Rect> regions_to_copy; 307 std::vector<gfx::Rect> regions_to_copy;
286 GetRegionsToCopy(previous_damage_rect_, new_damage_rect, &regions_to_copy); 308 GetRegionsToCopy(previous_damage_rect_, new_damage_rect, &regions_to_copy);
287 309
288 ScopedFrameBufferBinder fbo_binder(fbo_id_); 310 ScopedFrameBufferBinder fbo_binder(fbo_id_);
289 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, 311 glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
290 GL_COLOR_ATTACHMENT0, 312 GL_COLOR_ATTACHMENT0,
291 GL_TEXTURE_2D, 313 GL_TEXTURE_2D,
292 front_texture_service_id, 314 front_texture_service_id,
293 0); 315 0);
294 ScopedTextureBinder texture_binder(back_texture_service_id); 316 ScopedTextureBinder texture_binder(back_texture_service_id);
295 317
296 for (size_t i = 0; i < regions_to_copy.size(); ++i) { 318 for (size_t i = 0; i < regions_to_copy.size(); ++i) {
297 const gfx::Rect& region_to_copy = regions_to_copy[i]; 319 const gfx::Rect& region_to_copy = regions_to_copy[i];
298 if (!region_to_copy.IsEmpty()) { 320 if (!region_to_copy.IsEmpty()) {
299 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, region_to_copy.x(), 321 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, region_to_copy.x(),
300 region_to_copy.y(), region_to_copy.x(), region_to_copy.y(), 322 region_to_copy.y(), region_to_copy.x(), region_to_copy.y(),
301 region_to_copy.width(), region_to_copy.height()); 323 region_to_copy.width(), region_to_copy.height());
302 } 324 }
303 } 325 }
304 } else { 326 } else {
305 DCHECK(new_damage_rect == gfx::Rect(expected_size)); 327 DCHECK(new_damage_rect == gfx::Rect(expected_size));
306 } 328 }
307 329
308 glFlush(); 330 glFlush();
309 front_ = back(); 331 front_ = back();
332 previous_damage_rect_ = new_damage_rect;
333
334 DCHECK(textures_[front()].client_id);
310 335
311 GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params params; 336 GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params params;
312 params.surface_handle = textures_[front_].client_id; 337 params.surface_handle = textures_[front()].client_id;
313 params.x = x; 338 params.x = x;
314 params.y = y; 339 params.y = y;
315 params.width = width; 340 params.width = width;
316 params.height = height; 341 params.height = height;
342 params.visibility_state_id = visibility_state_id_;
317 helper_->SendAcceleratedSurfacePostSubBuffer(params); 343 helper_->SendAcceleratedSurfacePostSubBuffer(params);
318 helper_->SetScheduled(false); 344 helper_->SetScheduled(false);
319
320 previous_damage_rect_ = new_damage_rect;
321 return true; 345 return true;
322 } 346 }
323 347
324 std::string TextureImageTransportSurface::GetExtensions() { 348 std::string TextureImageTransportSurface::GetExtensions() {
325 std::string extensions = gfx::GLSurface::GetExtensions(); 349 std::string extensions = gfx::GLSurface::GetExtensions();
326 extensions += extensions.empty() ? "" : " "; 350 extensions += extensions.empty() ? "" : " ";
327 extensions += "GL_CHROMIUM_front_buffer_cached "; 351 extensions += "GL_CHROMIUM_front_buffer_cached ";
328 extensions += "GL_CHROMIUM_post_sub_buffer"; 352 extensions += "GL_CHROMIUM_post_sub_buffer";
329 return extensions; 353 return extensions;
330 } 354 }
331 355
332 gfx::Size TextureImageTransportSurface::GetSize() { 356 gfx::Size TextureImageTransportSurface::GetSize() {
333 return textures_[back()].size; 357 return textures_[back()].size;
334 } 358 }
335 359
336 void* TextureImageTransportSurface::GetHandle() { 360 void* TextureImageTransportSurface::GetHandle() {
337 return parent_stub_ ? parent_stub_->surface()->GetHandle() : NULL; 361 return parent_stub_ ? parent_stub_->surface()->GetHandle() : NULL;
338 } 362 }
339 363
340 364
341 void TextureImageTransportSurface::OnNewSurfaceACK( 365 void TextureImageTransportSurface::OnNewSurfaceACK(
342 uint64 surface_handle, TransportDIB::Handle /*shm_handle*/) { 366 uint64 surface_handle, TransportDIB::Handle /*shm_handle*/) {
343 } 367 }
344 368
369 void TextureImageTransportSurface::OnSetFrontSurfaceIsProtected(
370 bool is_protected, uint32 visibility_state_id) {
371 visibility_state_id_ = visibility_state_id;
372 if (frontbuffer_is_protected_ == is_protected)
373 return;
374 frontbuffer_is_protected_ = is_protected;
375 AdjustFrontBufferAllocation();
376
377 // If surface is set to protected, and we haven't actually released it yet,
378 // we can set the ui surface handle now just by sending a swap message.
379 if (is_protected && textures_[front()].info->service_id() &&
380 textures_[front()].sent_to_client) {
381 GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params;
382 params.surface_handle = textures_[front()].client_id;
383 params.visibility_state_id = visibility_state_id_;
384 params.require_ack = false;
385 helper_->SendAcceleratedSurfaceBuffersSwapped(params);
386 }
387 }
388
345 void TextureImageTransportSurface::OnBuffersSwappedACK() { 389 void TextureImageTransportSurface::OnBuffersSwappedACK() {
346 if (helper_->MakeCurrent()) { 390 if (helper_->MakeCurrent()) {
347 if (textures_[front_].size != textures_[back()].size) { 391 if (textures_[front()].size != textures_[back()].size ||
348 CreateBackTexture(textures_[front_].size); 392 !textures_[back()].info->service_id() ||
393 !textures_[back()].sent_to_client) {
394 // We may get an ACK from a stale swap just to reschedule. In that case,
395 // we may not have a backbuffer suggestion and should not recreate one.
396 if (backbuffer_suggested_allocation_)
397 CreateBackTexture(textures_[front()].size);
349 } else { 398 } else {
350 AttachBackTextureToFBO(); 399 AttachBackTextureToFBO();
351 } 400 }
352 } 401 }
353 402
354 // Even if MakeCurrent fails, schedule anyway, to trigger the lost context 403 // Even if MakeCurrent fails, schedule anyway, to trigger the lost context
355 // logic. 404 // logic.
356 helper_->SetScheduled(true); 405 helper_->SetScheduled(true);
357 } 406 }
358 407
359 void TextureImageTransportSurface::OnPostSubBufferACK() { 408 void TextureImageTransportSurface::OnPostSubBufferACK() {
360 OnBuffersSwappedACK(); 409 OnBuffersSwappedACK();
361 } 410 }
362 411
363 void TextureImageTransportSurface::OnResizeViewACK() { 412 void TextureImageTransportSurface::OnResizeViewACK() {
364 NOTREACHED(); 413 NOTREACHED();
365 } 414 }
366 415
367 void TextureImageTransportSurface::ReleaseBackTexture() { 416 void TextureImageTransportSurface::ReleaseTexture(int id) {
368 if (!parent_stub_) 417 if (!parent_stub_)
369 return; 418 return;
370 TextureInfo* info = textures_[back()].info; 419 Texture& texture = textures_[id];
420 TextureInfo* info = texture.info;
371 DCHECK(info); 421 DCHECK(info);
372 422
373 GLuint service_id = info->service_id(); 423 GLuint service_id = info->service_id();
374 if (!service_id) 424 if (!service_id)
375 return; 425 return;
376 info->SetServiceId(0); 426 info->SetServiceId(0);
377 427
378 { 428 {
379 ScopedFrameBufferBinder fbo_binder(fbo_id_); 429 ScopedFrameBufferBinder fbo_binder(fbo_id_);
380 glDeleteTextures(1, &service_id); 430 glDeleteTextures(1, &service_id);
381 } 431 }
382 glFlush(); 432 glFlush();
383 CHECK_GL_ERROR(); 433 CHECK_GL_ERROR();
384 } 434 }
385 435
386 void TextureImageTransportSurface::CreateBackTexture(const gfx::Size& size) { 436 void TextureImageTransportSurface::CreateBackTexture(const gfx::Size& size) {
387 if (!parent_stub_) 437 if (!parent_stub_)
388 return; 438 return;
389 Texture& texture = textures_[back()]; 439 Texture& texture = textures_[back()];
390 TextureInfo* info = texture.info; 440 TextureInfo* info = texture.info;
391 DCHECK(info); 441 DCHECK(info);
392 442
393 GLuint service_id = info->service_id(); 443 GLuint service_id = info->service_id();
394 444
395 if (service_id && texture.size == size) 445 if (service_id && texture.size == size && texture.sent_to_client)
396 return; 446 return;
397 447
398 if (!service_id) { 448 if (!service_id) {
399 glGenTextures(1, &service_id); 449 glGenTextures(1, &service_id);
400 info->SetServiceId(service_id); 450 info->SetServiceId(service_id);
401 } 451 }
402 452
403 if (size != texture.size) { 453 if (size != texture.size) {
404 texture.size = size; 454 texture.size = size;
405 TextureManager* texture_manager = 455 TextureManager* texture_manager =
(...skipping 30 matching lines...) Expand all
436 params.width = size.width(); 486 params.width = size.width();
437 params.height = size.height(); 487 params.height = size.height();
438 params.surface_handle = texture.client_id; 488 params.surface_handle = texture.client_id;
439 helper_->SendAcceleratedSurfaceNew(params); 489 helper_->SendAcceleratedSurfaceNew(params);
440 texture.sent_to_client = true; 490 texture.sent_to_client = true;
441 } 491 }
442 492
443 void TextureImageTransportSurface::AttachBackTextureToFBO() { 493 void TextureImageTransportSurface::AttachBackTextureToFBO() {
444 if (!parent_stub_) 494 if (!parent_stub_)
445 return; 495 return;
446 DCHECK(textures_[back()].info); 496 TextureInfo* info = textures_[back()].info;
497 DCHECK(info);
447 498
448 ScopedFrameBufferBinder fbo_binder(fbo_id_); 499 ScopedFrameBufferBinder fbo_binder(fbo_id_);
449 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, 500 glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
450 GL_COLOR_ATTACHMENT0, 501 GL_COLOR_ATTACHMENT0,
451 GL_TEXTURE_2D, 502 GL_TEXTURE_2D,
452 textures_[back()].info->service_id(), 503 info->service_id(),
453 0); 504 0);
454 glFlush(); 505 glFlush();
455 CHECK_GL_ERROR(); 506 CHECK_GL_ERROR();
456 507
457 #ifndef NDEBUG 508 #ifndef NDEBUG
458 GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); 509 GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
459 if (status != GL_FRAMEBUFFER_COMPLETE) { 510 if (status != GL_FRAMEBUFFER_COMPLETE) {
460 DLOG(ERROR) << "Framebuffer incomplete."; 511 DLOG(ERROR) << "Framebuffer incomplete.";
461 } 512 }
462 #endif 513 #endif
463 } 514 }
464 515
465 void TextureImageTransportSurface::ReleaseParentStub() { 516 void TextureImageTransportSurface::ReleaseParentStub() {
466 DCHECK(parent_stub_); 517 DCHECK(parent_stub_);
467 parent_stub_->RemoveDestructionObserver(this); 518 parent_stub_->RemoveDestructionObserver(this);
468 for (int i = 0; i < 2; ++i) { 519 for (int i = 0; i < 2; ++i) {
469 Texture& texture = textures_[i]; 520 Texture& texture = textures_[i];
470 texture.info = NULL; 521 texture.info = NULL;
471 if (!texture.sent_to_client) 522 if (!texture.sent_to_client)
472 continue; 523 continue;
473 GpuHostMsg_AcceleratedSurfaceRelease_Params params; 524 GpuHostMsg_AcceleratedSurfaceRelease_Params params;
474 params.identifier = texture.client_id; 525 params.identifier = texture.client_id;
475 helper_->SendAcceleratedSurfaceRelease(params); 526 helper_->SendAcceleratedSurfaceRelease(params);
476 } 527 }
477 parent_stub_ = NULL; 528 parent_stub_ = NULL;
478 } 529 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698