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

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: minor changes, rebasing with master 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 "content/common/gpu/gpu_channel.h" 7 #include "content/common/gpu/gpu_channel.h"
8 #include "content/common/gpu/gpu_channel_manager.h" 8 #include "content/common/gpu/gpu_channel_manager.h"
9 #include "content/common/gpu/gpu_messages.h" 9 #include "content/common/gpu/gpu_messages.h"
10 #include "gpu/command_buffer/service/context_group.h" 10 #include "gpu/command_buffer/service/context_group.h"
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 60
61 TextureImageTransportSurface::TextureImageTransportSurface( 61 TextureImageTransportSurface::TextureImageTransportSurface(
62 GpuChannelManager* manager, 62 GpuChannelManager* manager,
63 GpuCommandBufferStub* stub, 63 GpuCommandBufferStub* stub,
64 const gfx::GLSurfaceHandle& handle) 64 const gfx::GLSurfaceHandle& handle)
65 : fbo_id_(0), 65 : fbo_id_(0),
66 front_(0), 66 front_(0),
67 stub_destroyed_(false), 67 stub_destroyed_(false),
68 backbuffer_suggested_allocation_(true), 68 backbuffer_suggested_allocation_(true),
69 frontbuffer_suggested_allocation_(true), 69 frontbuffer_suggested_allocation_(true),
70 frontbuffer_is_protected_(true),
71 ui_may_not_have_frontbuffer_handle_(false),
72 current_valid_release_front_request_id_(0),
73 next_unique_release_front_request_id_(0),
70 parent_stub_(NULL) { 74 parent_stub_(NULL) {
71 GpuChannel* parent_channel = manager->LookupChannel(handle.parent_client_id); 75 GpuChannel* parent_channel = manager->LookupChannel(handle.parent_client_id);
72 DCHECK(parent_channel); 76 DCHECK(parent_channel);
73 parent_stub_ = parent_channel->LookupCommandBuffer(handle.parent_context_id); 77 parent_stub_ = parent_channel->LookupCommandBuffer(handle.parent_context_id);
74 DCHECK(parent_stub_); 78 DCHECK(parent_stub_);
75 parent_stub_->AddDestructionObserver(this); 79 parent_stub_->AddDestructionObserver(this);
76 TextureManager* texture_manager = 80 TextureManager* texture_manager =
77 parent_stub_->decoder()->GetContextGroup()->texture_manager(); 81 parent_stub_->decoder()->GetContextGroup()->texture_manager();
78 DCHECK(texture_manager); 82 DCHECK(texture_manager);
79 83
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
161 if (backbuffer_suggested_allocation_ == allocation) 165 if (backbuffer_suggested_allocation_ == allocation)
162 return; 166 return;
163 backbuffer_suggested_allocation_ = allocation; 167 backbuffer_suggested_allocation_ = allocation;
164 168
165 if (!helper_->MakeCurrent()) 169 if (!helper_->MakeCurrent())
166 return; 170 return;
167 171
168 if (backbuffer_suggested_allocation_) 172 if (backbuffer_suggested_allocation_)
169 CreateBackTexture(textures_[back()].size); 173 CreateBackTexture(textures_[back()].size);
170 else 174 else
171 ReleaseBackTexture(); 175 ReleaseTexture(back());
172 } 176 }
173 177
174 void TextureImageTransportSurface::SetFrontbufferAllocation(bool allocation) { 178 void TextureImageTransportSurface::SetFrontbufferAllocation(bool allocation) {
175 if (frontbuffer_suggested_allocation_ == allocation) 179 if (frontbuffer_suggested_allocation_ == allocation)
176 return; 180 return;
177 frontbuffer_suggested_allocation_ = allocation; 181 frontbuffer_suggested_allocation_ = allocation;
182 AdjustFrontBufferAllocation(0);
183 }
184
185 void TextureImageTransportSurface::AdjustFrontBufferAllocation(
186 int retry_count) {
187 if (!helper_->MakeCurrent())
188 return;
189
190 if (!frontbuffer_suggested_allocation_ &&
191 textures_[front()].info->service_id() &&
192 !frontbuffer_is_protected_)
193 RequestReleaseFrontTexture(retry_count);
178 } 194 }
179 195
180 void* TextureImageTransportSurface::GetShareHandle() { 196 void* TextureImageTransportSurface::GetShareHandle() {
181 return GetHandle(); 197 return GetHandle();
182 } 198 }
183 199
184 void* TextureImageTransportSurface::GetDisplay() { 200 void* TextureImageTransportSurface::GetDisplay() {
185 return parent_stub_ ? parent_stub_->surface()->GetDisplay() : NULL; 201 return parent_stub_ ? parent_stub_->surface()->GetDisplay() : NULL;
186 } 202 }
187 203
(...skipping 15 matching lines...) Expand all
203 // resources we allocated in the stub's context. 219 // resources we allocated in the stub's context.
204 glDeleteFramebuffersEXT(1, &fbo_id_); 220 glDeleteFramebuffersEXT(1, &fbo_id_);
205 CHECK_GL_ERROR(); 221 CHECK_GL_ERROR();
206 fbo_id_ = 0; 222 fbo_id_ = 0;
207 223
208 stub_destroyed_ = true; 224 stub_destroyed_ = true;
209 } 225 }
210 } 226 }
211 227
212 bool TextureImageTransportSurface::SwapBuffers() { 228 bool TextureImageTransportSurface::SwapBuffers() {
229 current_valid_release_front_request_id_ = 0;
213 DCHECK(backbuffer_suggested_allocation_); 230 DCHECK(backbuffer_suggested_allocation_);
214 if (!frontbuffer_suggested_allocation_) 231 if (!frontbuffer_suggested_allocation_)
215 return true; 232 return true;
216 if (!parent_stub_) { 233 if (!parent_stub_) {
217 LOG(ERROR) << "SwapBuffers failed because no parent stub."; 234 LOG(ERROR) << "SwapBuffers failed because no parent stub.";
218 return false; 235 return false;
219 } 236 }
220 237
221 glFlush(); 238 glFlush();
222 front_ = back(); 239 front_ = back();
223 previous_damage_rect_ = gfx::Rect(textures_[front_].size); 240 previous_damage_rect_ = gfx::Rect(textures_[front()].size);
224 241
225 DCHECK(textures_[front_].client_id != 0); 242 DCHECK(textures_[front()].client_id != 0);
226 243
227 GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params; 244 GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params;
228 params.surface_handle = textures_[front_].client_id; 245 params.surface_handle = textures_[front()].client_id;
229 helper_->SendAcceleratedSurfaceBuffersSwapped(params); 246 helper_->SendAcceleratedSurfaceBuffersSwapped(params);
230 helper_->SetScheduled(false); 247 helper_->SetScheduled(false);
231 return true; 248 return true;
232 } 249 }
233 250
234 bool TextureImageTransportSurface::PostSubBuffer( 251 bool TextureImageTransportSurface::PostSubBuffer(
235 int x, int y, int width, int height) { 252 int x, int y, int width, int height) {
253 current_valid_release_front_request_id_ = 0;
236 DCHECK(backbuffer_suggested_allocation_); 254 DCHECK(backbuffer_suggested_allocation_);
237 if (!frontbuffer_suggested_allocation_) 255 if (!frontbuffer_suggested_allocation_)
238 return true; 256 return true;
239 // If we are recreating the frontbuffer with this swap, make sure we are 257 // If we are recreating the frontbuffer with this swap, make sure we are
240 // drawing a full frame. 258 // drawing a full frame.
241 DCHECK(textures_[front_].info->service_id() || 259 DCHECK(textures_[front_].info->service_id() ||
242 (!x && !y && gfx::Size(width, height) == textures_[back()].size)); 260 (!x && !y && gfx::Size(width, height) == textures_[back()].size));
243 if (!parent_stub_) { 261 if (!parent_stub_) {
244 LOG(ERROR) << "PostSubBuffer failed because no parent stub."; 262 LOG(ERROR) << "PostSubBuffer failed because no parent stub.";
245 return false; 263 return false;
246 } 264 }
247 265
248 DCHECK(textures_[back()].info);
249 int back_texture_service_id = textures_[back()].info->service_id();
250
251 DCHECK(textures_[front_].info);
252 int front_texture_service_id = textures_[front_].info->service_id();
253
254 gfx::Size expected_size = textures_[back()].size;
255 bool surfaces_same_size = textures_[front_].size == expected_size;
256
257 const gfx::Rect new_damage_rect(x, y, width, height); 266 const gfx::Rect new_damage_rect(x, y, width, height);
258 267
259 // An empty damage rect is a successful no-op. 268 // An empty damage rect is a successful no-op.
260 if (new_damage_rect.IsEmpty()) 269 if (new_damage_rect.IsEmpty())
261 return true; 270 return true;
262 271
272 int back_texture_service_id = textures_[back()].info->service_id();
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
263 if (surfaces_same_size) { 278 if (surfaces_same_size) {
264 std::vector<gfx::Rect> regions_to_copy; 279 std::vector<gfx::Rect> regions_to_copy;
265 GetRegionsToCopy(previous_damage_rect_, new_damage_rect, &regions_to_copy); 280 GetRegionsToCopy(previous_damage_rect_, new_damage_rect, &regions_to_copy);
266 281
267 ScopedFrameBufferBinder fbo_binder(fbo_id_); 282 ScopedFrameBufferBinder fbo_binder(fbo_id_);
268 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, 283 glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
269 GL_COLOR_ATTACHMENT0, 284 GL_COLOR_ATTACHMENT0,
270 GL_TEXTURE_2D, 285 GL_TEXTURE_2D,
271 front_texture_service_id, 286 front_texture_service_id,
272 0); 287 0);
273 ScopedTextureBinder texture_binder(back_texture_service_id); 288 ScopedTextureBinder texture_binder(back_texture_service_id);
274 289
275 for (size_t i = 0; i < regions_to_copy.size(); ++i) { 290 for (size_t i = 0; i < regions_to_copy.size(); ++i) {
276 const gfx::Rect& region_to_copy = regions_to_copy[i]; 291 const gfx::Rect& region_to_copy = regions_to_copy[i];
277 if (!region_to_copy.IsEmpty()) { 292 if (!region_to_copy.IsEmpty()) {
278 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, region_to_copy.x(), 293 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, region_to_copy.x(),
279 region_to_copy.y(), region_to_copy.x(), region_to_copy.y(), 294 region_to_copy.y(), region_to_copy.x(), region_to_copy.y(),
280 region_to_copy.width(), region_to_copy.height()); 295 region_to_copy.width(), region_to_copy.height());
281 } 296 }
282 } 297 }
283 } else { 298 } else {
284 DCHECK(new_damage_rect == gfx::Rect(expected_size)); 299 DCHECK(new_damage_rect == gfx::Rect(expected_size));
285 } 300 }
286 301
287 glFlush(); 302 glFlush();
288 front_ = back(); 303 front_ = back();
304 previous_damage_rect_ = new_damage_rect;
305
306 DCHECK(textures_[front()].client_id != 0);
289 307
290 GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params params; 308 GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params params;
291 params.surface_handle = textures_[front_].client_id; 309 params.surface_handle = textures_[front()].client_id;
292 params.x = x; 310 params.x = x;
293 params.y = y; 311 params.y = y;
294 params.width = width; 312 params.width = width;
295 params.height = height; 313 params.height = height;
296 helper_->SendAcceleratedSurfacePostSubBuffer(params); 314 helper_->SendAcceleratedSurfacePostSubBuffer(params);
297 helper_->SetScheduled(false); 315 helper_->SetScheduled(false);
298
299 previous_damage_rect_ = new_damage_rect;
300 return true; 316 return true;
301 } 317 }
302 318
303 std::string TextureImageTransportSurface::GetExtensions() { 319 std::string TextureImageTransportSurface::GetExtensions() {
304 std::string extensions = gfx::GLSurface::GetExtensions(); 320 std::string extensions = gfx::GLSurface::GetExtensions();
305 extensions += extensions.empty() ? "" : " "; 321 extensions += extensions.empty() ? "" : " ";
306 extensions += "GL_CHROMIUM_front_buffer_cached "; 322 extensions += "GL_CHROMIUM_front_buffer_cached ";
307 extensions += "GL_CHROMIUM_post_sub_buffer"; 323 extensions += "GL_CHROMIUM_post_sub_buffer";
308 return extensions; 324 return extensions;
309 } 325 }
310 326
311 gfx::Size TextureImageTransportSurface::GetSize() { 327 gfx::Size TextureImageTransportSurface::GetSize() {
312 return textures_[back()].size; 328 return textures_[back()].size;
313 } 329 }
314 330
315 void* TextureImageTransportSurface::GetHandle() { 331 void* TextureImageTransportSurface::GetHandle() {
316 return parent_stub_ ? parent_stub_->surface()->GetHandle() : NULL; 332 return parent_stub_ ? parent_stub_->surface()->GetHandle() : NULL;
317 } 333 }
318 334
319 335
320 void TextureImageTransportSurface::OnNewSurfaceACK( 336 void TextureImageTransportSurface::OnNewSurfaceACK(
321 uint64 surface_handle, TransportDIB::Handle /*shm_handle*/) { 337 uint64 surface_handle, TransportDIB::Handle /*shm_handle*/) {
322 } 338 }
323 339
340 void TextureImageTransportSurface::OnSetFrontSurfaceIsProtected(
341 bool is_protected) {
342 if (frontbuffer_is_protected_ == is_protected)
343 return;
344 frontbuffer_is_protected_ = is_protected;
345 AdjustFrontBufferAllocation(0);
346 }
347
348 void TextureImageTransportSurface::OnRequestReleaseFrontACK(
349 int request_id, int retry_count, bool was_released) {
350 if (!was_released) {
351 // If the browser ignored out request, but the request id is still valid,
352 // call AdjustFrontBufferAllocation, which will send another request only if
353 // it still makes sense to do so. This can happen with visibility ABA
354 // transitions.
355 if (request_id == current_valid_release_front_request_id_ &&
356 retry_count < kMaxRequestReleaseFrontRetries)
357 AdjustFrontBufferAllocation(retry_count + 1);
358 return;
359 }
360 if (frontbuffer_suggested_allocation_ || frontbuffer_is_protected_ ||
361 request_id != current_valid_release_front_request_id_)
362 return;
363 Texture& texture = textures_[front()];
364 texture.sent_to_client = false;
365 ReleaseTexture(front());
366 }
367
324 void TextureImageTransportSurface::OnBuffersSwappedACK() { 368 void TextureImageTransportSurface::OnBuffersSwappedACK() {
325 if (helper_->MakeCurrent()) { 369 if (helper_->MakeCurrent()) {
326 if (textures_[front_].size != textures_[back()].size) { 370 if (textures_[front()].size != textures_[back()].size ||
327 CreateBackTexture(textures_[front_].size); 371 !textures_[back()].info->service_id() ||
372 !textures_[back()].sent_to_client ||
373 ui_may_not_have_frontbuffer_handle_) {
374 CreateBackTexture(textures_[front()].size);
375 ui_may_not_have_frontbuffer_handle_ = false;
328 } else { 376 } else {
329 AttachBackTextureToFBO(); 377 AttachBackTextureToFBO();
330 } 378 }
331 } 379 }
332 380
333 // Even if MakeCurrent fails, schedule anyway, to trigger the lost context 381 // Even if MakeCurrent fails, schedule anyway, to trigger the lost context
334 // logic. 382 // logic.
335 helper_->SetScheduled(true); 383 helper_->SetScheduled(true);
336 } 384 }
337 385
338 void TextureImageTransportSurface::OnPostSubBufferACK() { 386 void TextureImageTransportSurface::OnPostSubBufferACK() {
339 OnBuffersSwappedACK(); 387 OnBuffersSwappedACK();
340 } 388 }
341 389
342 void TextureImageTransportSurface::OnResizeViewACK() { 390 void TextureImageTransportSurface::OnResizeViewACK() {
343 NOTREACHED(); 391 NOTREACHED();
344 } 392 }
345 393
346 void TextureImageTransportSurface::ReleaseBackTexture() { 394 void TextureImageTransportSurface::RequestReleaseFrontTexture(int retry_count) {
395 Texture& texture = textures_[front()];
396 DCHECK(texture.info);
397 DCHECK(texture.info->service_id());
398 if (!texture.sent_to_client) {
399 ReleaseTexture(front());
400 return;
401 }
402 if (!retry_count)
403 current_valid_release_front_request_id_ =
404 ++next_unique_release_front_request_id_;
405 GpuHostMsg_AcceleratedSurfaceRequestReleaseFront_Params params;
406 params.identifier = texture.client_id;
407 params.request_id = current_valid_release_front_request_id_;
408 params.retry_count = retry_count;
409 helper_->SendAcceleratedSurfaceRequestReleaseFront(params);
410 ui_may_not_have_frontbuffer_handle_ = true;
411 }
412
413 void TextureImageTransportSurface::ReleaseTexture(int id) {
347 if (!parent_stub_) 414 if (!parent_stub_)
348 return; 415 return;
349 TextureInfo* info = textures_[back()].info; 416 Texture& texture = textures_[id];
417 TextureInfo* info = texture.info;
350 DCHECK(info); 418 DCHECK(info);
351 419
352 GLuint service_id = info->service_id(); 420 GLuint service_id = info->service_id();
353 if (!service_id) 421 if (!service_id)
354 return; 422 return;
355 info->SetServiceId(0); 423 info->SetServiceId(0);
356 424
357 { 425 {
358 ScopedFrameBufferBinder fbo_binder(fbo_id_); 426 ScopedFrameBufferBinder fbo_binder(fbo_id_);
359 glDeleteTextures(1, &service_id); 427 glDeleteTextures(1, &service_id);
360 } 428 }
361 glFlush(); 429 glFlush();
362 CHECK_GL_ERROR(); 430 CHECK_GL_ERROR();
363 } 431 }
364 432
365 void TextureImageTransportSurface::CreateBackTexture(const gfx::Size& size) { 433 void TextureImageTransportSurface::CreateBackTexture(const gfx::Size& size) {
366 if (!parent_stub_) 434 if (!parent_stub_)
367 return; 435 return;
368 Texture& texture = textures_[back()]; 436 Texture& texture = textures_[back()];
369 TextureInfo* info = texture.info; 437 TextureInfo* info = texture.info;
370 DCHECK(info); 438 DCHECK(info);
371 439
372 GLuint service_id = info->service_id(); 440 GLuint service_id = info->service_id();
373 441
374 if (service_id && texture.size == size) 442 if (service_id && texture.size == size &&
443 !ui_may_not_have_frontbuffer_handle_ && texture.sent_to_client)
375 return; 444 return;
376 445
377 if (!service_id) { 446 if (!service_id) {
378 glGenTextures(1, &service_id); 447 glGenTextures(1, &service_id);
379 info->SetServiceId(service_id); 448 info->SetServiceId(service_id);
380 } 449 }
381 450
382 if (size != texture.size) { 451 if (size != texture.size) {
383 texture.size = size; 452 texture.size = size;
384 TextureManager* texture_manager = 453 TextureManager* texture_manager =
(...skipping 30 matching lines...) Expand all
415 params.width = size.width(); 484 params.width = size.width();
416 params.height = size.height(); 485 params.height = size.height();
417 params.surface_handle = texture.client_id; 486 params.surface_handle = texture.client_id;
418 helper_->SendAcceleratedSurfaceNew(params); 487 helper_->SendAcceleratedSurfaceNew(params);
419 texture.sent_to_client = true; 488 texture.sent_to_client = true;
420 } 489 }
421 490
422 void TextureImageTransportSurface::AttachBackTextureToFBO() { 491 void TextureImageTransportSurface::AttachBackTextureToFBO() {
423 if (!parent_stub_) 492 if (!parent_stub_)
424 return; 493 return;
425 DCHECK(textures_[back()].info); 494 TextureInfo* info = textures_[back()].info;
495 DCHECK(info);
426 496
427 ScopedFrameBufferBinder fbo_binder(fbo_id_); 497 ScopedFrameBufferBinder fbo_binder(fbo_id_);
428 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, 498 glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
429 GL_COLOR_ATTACHMENT0, 499 GL_COLOR_ATTACHMENT0,
430 GL_TEXTURE_2D, 500 GL_TEXTURE_2D,
431 textures_[back()].info->service_id(), 501 info->service_id(),
432 0); 502 0);
433 glFlush(); 503 glFlush();
434 CHECK_GL_ERROR(); 504 CHECK_GL_ERROR();
435 505
436 #ifndef NDEBUG 506 #ifndef NDEBUG
437 GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); 507 GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
438 if (status != GL_FRAMEBUFFER_COMPLETE) { 508 if (status != GL_FRAMEBUFFER_COMPLETE) {
439 DLOG(ERROR) << "Framebuffer incomplete."; 509 DLOG(ERROR) << "Framebuffer incomplete.";
440 } 510 }
441 #endif 511 #endif
442 } 512 }
443 513
444 void TextureImageTransportSurface::ReleaseParentStub() { 514 void TextureImageTransportSurface::ReleaseParentStub() {
445 DCHECK(parent_stub_); 515 DCHECK(parent_stub_);
446 parent_stub_->RemoveDestructionObserver(this); 516 parent_stub_->RemoveDestructionObserver(this);
447 for (int i = 0; i < 2; ++i) { 517 for (int i = 0; i < 2; ++i) {
448 Texture& texture = textures_[i]; 518 Texture& texture = textures_[i];
449 texture.info = NULL; 519 texture.info = NULL;
450 if (!texture.sent_to_client) 520 if (!texture.sent_to_client)
451 continue; 521 continue;
452 GpuHostMsg_AcceleratedSurfaceRelease_Params params; 522 GpuHostMsg_AcceleratedSurfaceRelease_Params params;
453 params.identifier = texture.client_id; 523 params.identifier = texture.client_id;
454 helper_->SendAcceleratedSurfaceRelease(params); 524 helper_->SendAcceleratedSurfaceRelease(params);
455 } 525 }
456 parent_stub_ = NULL; 526 parent_stub_ = NULL;
457 } 527 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698