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

Side by Side Diff: cc/output/direct_renderer.cc

Issue 1028333002: Chromium -> Mojo roll. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 5 years, 9 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
« no previous file with comments | « cc/output/direct_renderer.h ('k') | cc/output/gl_renderer.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 1 // Copyright 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 "cc/output/direct_renderer.h" 5 #include "cc/output/direct_renderer.h"
6 6
7 #include <utility> 7 #include <utility>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/containers/hash_tables.h" 10 #include "base/containers/hash_tables.h"
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
271 return render_pass_scissor; 271 return render_pass_scissor;
272 } 272 }
273 273
274 bool DirectRenderer::NeedDeviceClip(const DrawingFrame* frame) const { 274 bool DirectRenderer::NeedDeviceClip(const DrawingFrame* frame) const {
275 if (frame->current_render_pass != frame->root_render_pass) 275 if (frame->current_render_pass != frame->root_render_pass)
276 return false; 276 return false;
277 277
278 return !frame->device_clip_rect.Contains(frame->device_viewport_rect); 278 return !frame->device_clip_rect.Contains(frame->device_viewport_rect);
279 } 279 }
280 280
281 gfx::Rect DirectRenderer::DeviceClipRectInWindowSpace(const DrawingFrame* frame) 281 gfx::Rect DirectRenderer::DeviceClipRectInDrawSpace(
282 const { 282 const DrawingFrame* frame) const {
283 gfx::Rect device_clip_rect = frame->device_clip_rect; 283 gfx::Rect device_clip_rect = frame->device_clip_rect;
284 if (FlippedFramebuffer(frame)) 284 device_clip_rect -= current_viewport_rect_.OffsetFromOrigin();
285 device_clip_rect.set_y(current_surface_size_.height() - 285 device_clip_rect += current_draw_rect_.OffsetFromOrigin();
286 device_clip_rect.bottom());
287 return device_clip_rect; 286 return device_clip_rect;
288 } 287 }
289 288
290 void DirectRenderer::SetScissorStateForQuad(const DrawingFrame* frame, 289 gfx::Rect DirectRenderer::DeviceViewportRectInDrawSpace(
291 const DrawQuad& quad) { 290 const DrawingFrame* frame) const {
292 if (quad.isClipped()) { 291 gfx::Rect device_viewport_rect = frame->device_viewport_rect;
293 SetScissorTestRectInDrawSpace(frame, quad.clipRect()); 292 device_viewport_rect -= current_viewport_rect_.OffsetFromOrigin();
294 return; 293 device_viewport_rect += current_draw_rect_.OffsetFromOrigin();
294 return device_viewport_rect;
295 }
296
297 gfx::Rect DirectRenderer::OutputSurfaceRectInDrawSpace(
298 const DrawingFrame* frame) const {
299 if (frame->current_render_pass == frame->root_render_pass) {
300 gfx::Rect output_surface_rect(output_surface_->SurfaceSize());
301 output_surface_rect -= current_viewport_rect_.OffsetFromOrigin();
302 output_surface_rect += current_draw_rect_.OffsetFromOrigin();
303 return output_surface_rect;
304 } else {
305 return frame->current_render_pass->output_rect;
295 } 306 }
296 if (NeedDeviceClip(frame)) {
297 SetScissorTestRect(DeviceClipRectInWindowSpace(frame));
298 return;
299 }
300
301 EnsureScissorTestDisabled();
302 } 307 }
303 308
304 bool DirectRenderer::ShouldSkipQuad(const DrawQuad& quad, 309 bool DirectRenderer::ShouldSkipQuad(const DrawQuad& quad,
305 const gfx::Rect& render_pass_scissor) { 310 const gfx::Rect& render_pass_scissor) {
306 if (render_pass_scissor.IsEmpty()) 311 if (render_pass_scissor.IsEmpty())
307 return true; 312 return true;
308 313
309 if (quad.isClipped()) { 314 if (quad.isClipped()) {
310 gfx::Rect r = quad.clipRect(); 315 gfx::Rect r = quad.clipRect();
311 r.Intersect(render_pass_scissor); 316 r.Intersect(render_pass_scissor);
312 return r.IsEmpty(); 317 return r.IsEmpty();
313 } 318 }
314 319
315 return false; 320 return false;
316 } 321 }
317 322
318 void DirectRenderer::SetScissorStateForQuadWithRenderPassScissor( 323 void DirectRenderer::SetScissorStateForQuad(
319 const DrawingFrame* frame, 324 const DrawingFrame* frame,
320 const DrawQuad& quad, 325 const DrawQuad& quad,
321 const gfx::Rect& render_pass_scissor) { 326 const gfx::Rect& render_pass_scissor,
322 gfx::Rect quad_scissor_rect = render_pass_scissor; 327 bool use_render_pass_scissor) {
323 if (quad.isClipped()) 328 if (use_render_pass_scissor) {
324 quad_scissor_rect.Intersect(quad.clipRect()); 329 gfx::Rect quad_scissor_rect = render_pass_scissor;
325 SetScissorTestRectInDrawSpace(frame, quad_scissor_rect); 330 if (quad.isClipped())
331 quad_scissor_rect.Intersect(quad.clipRect());
332 SetScissorTestRectInDrawSpace(frame, quad_scissor_rect);
333 return;
334 } else if (quad.isClipped()) {
335 SetScissorTestRectInDrawSpace(frame, quad.clipRect());
336 return;
337 }
338
339 EnsureScissorTestDisabled();
326 } 340 }
327 341
328 void DirectRenderer::SetScissorTestRectInDrawSpace( 342 void DirectRenderer::SetScissorTestRectInDrawSpace(
329 const DrawingFrame* frame, 343 const DrawingFrame* frame,
330 const gfx::Rect& draw_space_rect) { 344 const gfx::Rect& draw_space_rect) {
331 gfx::Rect window_space_rect = 345 gfx::Rect window_space_rect =
332 MoveFromDrawToWindowSpace(frame, draw_space_rect); 346 MoveFromDrawToWindowSpace(frame, draw_space_rect);
333 if (NeedDeviceClip(frame))
334 window_space_rect.Intersect(DeviceClipRectInWindowSpace(frame));
335 SetScissorTestRect(window_space_rect); 347 SetScissorTestRect(window_space_rect);
336 } 348 }
337 349
338 void DirectRenderer::FinishDrawingQuadList() {} 350 void DirectRenderer::FinishDrawingQuadList() {}
339 351
340 void DirectRenderer::DoDrawPolygon(const DrawPolygon& poly, 352 void DirectRenderer::DoDrawPolygon(const DrawPolygon& poly,
341 DrawingFrame* frame, 353 DrawingFrame* frame,
342 const gfx::Rect& render_pass_scissor, 354 const gfx::Rect& render_pass_scissor,
343 bool using_scissor_as_optimization) { 355 bool use_render_pass_scissor) {
344 if (using_scissor_as_optimization) { 356 SetScissorStateForQuad(frame, *poly.original_ref(), render_pass_scissor,
345 SetScissorStateForQuadWithRenderPassScissor(frame, *poly.original_ref(), 357 use_render_pass_scissor);
346 render_pass_scissor);
347 } else {
348 SetScissorStateForQuad(frame, *poly.original_ref());
349 }
350 358
351 // If the poly has not been split, then it is just a normal DrawQuad, 359 // If the poly has not been split, then it is just a normal DrawQuad,
352 // and we should save any extra processing that would have to be done. 360 // and we should save any extra processing that would have to be done.
353 if (!poly.is_split()) { 361 if (!poly.is_split()) {
354 DoDrawQuad(frame, poly.original_ref(), NULL); 362 DoDrawQuad(frame, poly.original_ref(), NULL);
355 return; 363 return;
356 } 364 }
357 365
358 std::vector<gfx::QuadF> quads; 366 std::vector<gfx::QuadF> quads;
359 poly.ToQuads2D(&quads); 367 poly.ToQuads2D(&quads);
360 for (size_t i = 0; i < quads.size(); ++i) { 368 for (size_t i = 0; i < quads.size(); ++i) {
361 DoDrawQuad(frame, poly.original_ref(), &quads[i]); 369 DoDrawQuad(frame, poly.original_ref(), &quads[i]);
362 } 370 }
363 } 371 }
364 372
365 void DirectRenderer::FlushPolygons(ScopedPtrDeque<DrawPolygon>* poly_list, 373 void DirectRenderer::FlushPolygons(ScopedPtrDeque<DrawPolygon>* poly_list,
366 DrawingFrame* frame, 374 DrawingFrame* frame,
367 const gfx::Rect& render_pass_scissor, 375 const gfx::Rect& render_pass_scissor,
368 bool using_scissor_as_optimization) { 376 bool use_render_pass_scissor) {
369 if (poly_list->empty()) { 377 if (poly_list->empty()) {
370 return; 378 return;
371 } 379 }
372 380
373 BspTree bsp_tree(poly_list); 381 BspTree bsp_tree(poly_list);
374 BspWalkActionDrawPolygon action_handler(this, frame, render_pass_scissor, 382 BspWalkActionDrawPolygon action_handler(this, frame, render_pass_scissor,
375 using_scissor_as_optimization); 383 use_render_pass_scissor);
376 bsp_tree.TraverseWithActionHandler(&action_handler); 384 bsp_tree.TraverseWithActionHandler(&action_handler);
377 DCHECK(poly_list->empty()); 385 DCHECK(poly_list->empty());
378 } 386 }
379 387
380 void DirectRenderer::DrawRenderPass(DrawingFrame* frame, 388 void DirectRenderer::DrawRenderPass(DrawingFrame* frame,
381 const RenderPass* render_pass) { 389 const RenderPass* render_pass) {
382 TRACE_EVENT0("cc", "DirectRenderer::DrawRenderPass"); 390 TRACE_EVENT0("cc", "DirectRenderer::DrawRenderPass");
383 if (!UseRenderPass(frame, render_pass)) 391 if (!UseRenderPass(frame, render_pass))
384 return; 392 return;
385 393
386 bool using_scissor_as_optimization = Capabilities().using_partial_swap; 394 const gfx::Rect surface_rect_in_draw_space =
387 gfx::Rect render_pass_scissor; 395 OutputSurfaceRectInDrawSpace(frame);
388 bool draw_rect_covers_full_surface = true; 396 gfx::Rect render_pass_scissor_in_draw_space = surface_rect_in_draw_space;
389 if (frame->current_render_pass == frame->root_render_pass &&
390 !frame->device_viewport_rect.Contains(
391 gfx::Rect(output_surface_->SurfaceSize())))
392 draw_rect_covers_full_surface = false;
393 397
394 if (using_scissor_as_optimization) { 398 if (frame->current_render_pass == frame->root_render_pass) {
395 render_pass_scissor = ComputeScissorRectForRenderPass(frame); 399 render_pass_scissor_in_draw_space.Intersect(
396 SetScissorTestRectInDrawSpace(frame, render_pass_scissor); 400 DeviceViewportRectInDrawSpace(frame));
397 if (!render_pass_scissor.Contains(frame->current_render_pass->output_rect))
398 draw_rect_covers_full_surface = false;
399 } 401 }
400 402
401 if (frame->current_render_pass != frame->root_render_pass || 403 if (Capabilities().using_partial_swap) {
402 settings_->should_clear_root_render_pass) { 404 render_pass_scissor_in_draw_space.Intersect(
403 if (NeedDeviceClip(frame)) { 405 ComputeScissorRectForRenderPass(frame));
404 SetScissorTestRect(DeviceClipRectInWindowSpace(frame)); 406 }
405 draw_rect_covers_full_surface = false;
406 } else if (!using_scissor_as_optimization) {
407 EnsureScissorTestDisabled();
408 }
409 407
410 bool has_external_stencil_test = 408 if (NeedDeviceClip(frame)) {
411 output_surface_->HasExternalStencilTest() && 409 render_pass_scissor_in_draw_space.Intersect(
412 frame->current_render_pass == frame->root_render_pass; 410 DeviceClipRectInDrawSpace(frame));
411 }
413 412
414 DiscardPixels(has_external_stencil_test, draw_rect_covers_full_surface); 413 bool render_pass_is_clipped =
415 ClearFramebuffer(frame, has_external_stencil_test); 414 !render_pass_scissor_in_draw_space.Contains(surface_rect_in_draw_space);
415 bool is_root_render_pass =
416 frame->current_render_pass == frame->root_render_pass;
417 bool has_external_stencil_test =
418 is_root_render_pass && output_surface_->HasExternalStencilTest();
419 bool should_clear_surface =
420 !has_external_stencil_test &&
421 (!is_root_render_pass || settings_->should_clear_root_render_pass);
422
423 // If |has_external_stencil_test| we can't discard or clear. Make sure we
424 // don't need to.
425 DCHECK_IMPLIES(has_external_stencil_test,
426 !frame->current_render_pass->has_transparent_background);
427
428 SurfaceInitializationMode mode;
429 if (should_clear_surface && render_pass_is_clipped) {
430 mode = SURFACE_INITIALIZATION_MODE_SCISSORED_CLEAR;
431 } else if (should_clear_surface) {
432 mode = SURFACE_INITIALIZATION_MODE_FULL_SURFACE_CLEAR;
433 } else {
434 mode = SURFACE_INITIALIZATION_MODE_PRESERVE;
416 } 435 }
417 436
437 PrepareSurfaceForPass(
438 frame, mode,
439 MoveFromDrawToWindowSpace(frame, render_pass_scissor_in_draw_space));
440
418 const QuadList& quad_list = render_pass->quad_list; 441 const QuadList& quad_list = render_pass->quad_list;
419 ScopedPtrDeque<DrawPolygon> poly_list; 442 ScopedPtrDeque<DrawPolygon> poly_list;
420 443
421 int next_polygon_id = 0; 444 int next_polygon_id = 0;
422 int last_sorting_context_id = 0; 445 int last_sorting_context_id = 0;
423 for (auto it = quad_list.BackToFrontBegin(); it != quad_list.BackToFrontEnd(); 446 for (auto it = quad_list.BackToFrontBegin(); it != quad_list.BackToFrontEnd();
424 ++it) { 447 ++it) {
425 const DrawQuad& quad = **it; 448 const DrawQuad& quad = **it;
426 gfx::QuadF send_quad(quad.visible_rect); 449 gfx::QuadF send_quad(quad.visible_rect);
427 450
428 if (using_scissor_as_optimization && 451 if (render_pass_is_clipped &&
429 ShouldSkipQuad(quad, render_pass_scissor)) { 452 ShouldSkipQuad(quad, render_pass_scissor_in_draw_space)) {
430 continue; 453 continue;
431 } 454 }
432 455
433 if (last_sorting_context_id != quad.shared_quad_state->sorting_context_id) { 456 if (last_sorting_context_id != quad.shared_quad_state->sorting_context_id) {
434 last_sorting_context_id = quad.shared_quad_state->sorting_context_id; 457 last_sorting_context_id = quad.shared_quad_state->sorting_context_id;
435 FlushPolygons(&poly_list, frame, render_pass_scissor, 458 FlushPolygons(&poly_list, frame, render_pass_scissor_in_draw_space,
436 using_scissor_as_optimization); 459 render_pass_is_clipped);
437 } 460 }
438 461
439 // This layer is in a 3D sorting context so we add it to the list of 462 // This layer is in a 3D sorting context so we add it to the list of
440 // polygons to go into the BSP tree. 463 // polygons to go into the BSP tree.
441 if (quad.shared_quad_state->sorting_context_id != 0) { 464 if (quad.shared_quad_state->sorting_context_id != 0) {
442 scoped_ptr<DrawPolygon> new_polygon(new DrawPolygon( 465 scoped_ptr<DrawPolygon> new_polygon(new DrawPolygon(
443 *it, quad.visible_rect, quad.quadTransform(), next_polygon_id++)); 466 *it, quad.visible_rect, quad.quadTransform(), next_polygon_id++));
444 if (new_polygon->points().size() > 2u) { 467 if (new_polygon->points().size() > 2u) {
445 poly_list.push_back(new_polygon.Pass()); 468 poly_list.push_back(new_polygon.Pass());
446 } 469 }
447 continue; 470 continue;
448 } 471 }
449 472
450 // We are not in a 3d sorting context, so we should draw the quad normally. 473 // We are not in a 3d sorting context, so we should draw the quad normally.
451 if (using_scissor_as_optimization) { 474 SetScissorStateForQuad(frame, quad, render_pass_scissor_in_draw_space,
452 SetScissorStateForQuadWithRenderPassScissor(frame, quad, 475 render_pass_is_clipped);
453 render_pass_scissor);
454 } else {
455 SetScissorStateForQuad(frame, quad);
456 }
457 476
458 DoDrawQuad(frame, &quad, nullptr); 477 DoDrawQuad(frame, &quad, nullptr);
459 } 478 }
460 FlushPolygons(&poly_list, frame, render_pass_scissor, 479 FlushPolygons(&poly_list, frame, render_pass_scissor_in_draw_space,
461 using_scissor_as_optimization); 480 render_pass_is_clipped);
462 FinishDrawingQuadList(); 481 FinishDrawingQuadList();
463 } 482 }
464 483
465 bool DirectRenderer::UseRenderPass(DrawingFrame* frame, 484 bool DirectRenderer::UseRenderPass(DrawingFrame* frame,
466 const RenderPass* render_pass) { 485 const RenderPass* render_pass) {
467 frame->current_render_pass = render_pass; 486 frame->current_render_pass = render_pass;
468 frame->current_texture = NULL; 487 frame->current_texture = NULL;
469 488
470 if (render_pass == frame->root_render_pass) { 489 if (render_pass == frame->root_render_pass) {
471 BindFramebufferToOutputSurface(frame); 490 BindFramebufferToOutputSurface(frame);
472 InitializeViewport(frame, 491 InitializeViewport(frame,
473 render_pass->output_rect, 492 render_pass->output_rect,
474 frame->device_viewport_rect, 493 frame->device_viewport_rect,
475 output_surface_->SurfaceSize()); 494 output_surface_->SurfaceSize());
476 return true; 495 return true;
477 } 496 }
478 497
479 ScopedResource* texture = render_pass_textures_.get(render_pass->id); 498 ScopedResource* texture = render_pass_textures_.get(render_pass->id);
480 DCHECK(texture); 499 DCHECK(texture);
481 500
482 gfx::Size size = RenderPassTextureSize(render_pass); 501 gfx::Size size = RenderPassTextureSize(render_pass);
483 size.Enlarge(enlarge_pass_texture_amount_.x(), 502 size.Enlarge(enlarge_pass_texture_amount_.x(),
484 enlarge_pass_texture_amount_.y()); 503 enlarge_pass_texture_amount_.y());
485 if (!texture->id()) 504 if (!texture->id())
486 texture->Allocate( 505 texture->Allocate(
487 size, ResourceProvider::TEXTURE_HINT_IMMUTABLE_FRAMEBUFFER, RGBA_8888); 506 size, ResourceProvider::TEXTURE_HINT_IMMUTABLE_FRAMEBUFFER, RGBA_8888);
488 DCHECK(texture->id()); 507 DCHECK(texture->id());
489 508
490 return BindFramebufferToTexture(frame, texture, render_pass->output_rect); 509 if (BindFramebufferToTexture(frame, texture, render_pass->output_rect)) {
510 InitializeViewport(frame, render_pass->output_rect,
511 gfx::Rect(render_pass->output_rect.size()),
512 render_pass->output_rect.size());
513 return true;
514 }
515
516 return false;
491 } 517 }
492 518
493 bool DirectRenderer::HasAllocatedResourcesForTesting(RenderPassId id) const { 519 bool DirectRenderer::HasAllocatedResourcesForTesting(RenderPassId id) const {
494 ScopedResource* texture = render_pass_textures_.get(id); 520 ScopedResource* texture = render_pass_textures_.get(id);
495 return texture && texture->id(); 521 return texture && texture->id();
496 } 522 }
497 523
498 // static 524 // static
499 gfx::Size DirectRenderer::RenderPassTextureSize(const RenderPass* render_pass) { 525 gfx::Size DirectRenderer::RenderPassTextureSize(const RenderPass* render_pass) {
500 return render_pass->output_rect.size(); 526 return render_pass->output_rect.size();
501 } 527 }
502 528
503 } // namespace cc 529 } // namespace cc
OLDNEW
« no previous file with comments | « cc/output/direct_renderer.h ('k') | cc/output/gl_renderer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698