| Index: cc/output/direct_renderer.cc
|
| diff --git a/cc/output/direct_renderer.cc b/cc/output/direct_renderer.cc
|
| index b068da0d052185e8daf130ef0103d956bb54a752..d2644666d1600491d954d9086c11869c64d7882c 100644
|
| --- a/cc/output/direct_renderer.cc
|
| +++ b/cc/output/direct_renderer.cc
|
| @@ -4,6 +4,9 @@
|
|
|
| #include "cc/output/direct_renderer.h"
|
|
|
| +#include <hash_map>
|
| +#include <list>
|
| +#include <set>
|
| #include <utility>
|
| #include <vector>
|
|
|
| @@ -12,6 +15,8 @@
|
| #include "base/debug/trace_event.h"
|
| #include "base/metrics/histogram.h"
|
| #include "cc/base/math_util.h"
|
| +#include "cc/output/bsp_tree.h"
|
| +#include "cc/output/bsp_walk_action.h"
|
| #include "cc/output/copy_output_request.h"
|
| #include "cc/quads/draw_quad.h"
|
| #include "ui/gfx/geometry/rect_conversions.h"
|
| @@ -299,22 +304,30 @@ void DirectRenderer::SetScissorStateForQuad(const DrawingFrame* frame,
|
| EnsureScissorTestDisabled();
|
| }
|
|
|
| +bool DirectRenderer::ShouldSkipQuad(
|
| + const DrawQuad& quad,
|
| + const gfx::Rect& render_pass_scissor
|
| + ) {
|
| + if(render_pass_scissor.IsEmpty())
|
| + return true;
|
| +
|
| + if (quad.isClipped()) {
|
| + gfx::Rect r = quad.clipRect();
|
| + r.Intersect(render_pass_scissor);
|
| + return r.IsEmpty();
|
| + }
|
| +
|
| + return false;
|
| +}
|
| +
|
| +
|
| void DirectRenderer::SetScissorStateForQuadWithRenderPassScissor(
|
| const DrawingFrame* frame,
|
| const DrawQuad& quad,
|
| - const gfx::Rect& render_pass_scissor,
|
| - bool* should_skip_quad) {
|
| + const gfx::Rect& render_pass_scissor) {
|
| gfx::Rect quad_scissor_rect = render_pass_scissor;
|
| -
|
| if (quad.isClipped())
|
| quad_scissor_rect.Intersect(quad.clipRect());
|
| -
|
| - if (quad_scissor_rect.IsEmpty()) {
|
| - *should_skip_quad = true;
|
| - return;
|
| - }
|
| -
|
| - *should_skip_quad = false;
|
| SetScissorTestRectInDrawSpace(frame, quad_scissor_rect);
|
| }
|
|
|
| @@ -329,6 +342,41 @@ void DirectRenderer::SetScissorTestRectInDrawSpace(
|
|
|
| void DirectRenderer::FinishDrawingQuadList() {}
|
|
|
| +void DirectRenderer::DoDrawPolygon(const DrawPolygon& poly,
|
| + DrawingFrame* frame,
|
| + const gfx::Rect& render_pass_scissor,
|
| + bool using_scissor_as_optimization) {
|
| + if (using_scissor_as_optimization) {
|
| + SetScissorStateForQuadWithRenderPassScissor(
|
| + frame, *poly.original_ref(), render_pass_scissor);
|
| + } else {
|
| + SetScissorStateForQuad(frame, *poly.original_ref());
|
| + }
|
| + std::vector<gfx::QuadF> quads;
|
| + poly.ToQuads2D(&quads);
|
| + for (unsigned int i = 0; i < quads.size(); ++i) {
|
| + DoDrawQuad(frame, poly.original_ref(), &quads[i]);
|
| + }
|
| +}
|
| +
|
| +void DirectRenderer::FlushPolygons(ScopedPtrDeque<DrawPolygon>* poly_list,
|
| + DrawingFrame* frame,
|
| + const gfx::Rect& render_pass_scissor,
|
| + bool using_scissor_as_optimization) {
|
| + if (poly_list->size() == 0) {
|
| + return;
|
| + }
|
| +
|
| + BspTree bsp_tree(poly_list);
|
| + // Very important to use a new list here because we're relying on the old
|
| + // list to be intact for cleanup
|
| + BspWalkActionDrawPolygon action_handler(this, frame, render_pass_scissor,
|
| + using_scissor_as_optimization);
|
| + bsp_tree.TraverseWithActionHandler(&action_handler);
|
| + // Clear the polygon list for the next transformation layer block
|
| + poly_list->clear();
|
| +}
|
| +
|
| void DirectRenderer::DrawRenderPass(DrawingFrame* frame,
|
| const RenderPass* render_pass) {
|
| TRACE_EVENT0("cc", "DirectRenderer::DrawRenderPass");
|
| @@ -368,22 +416,51 @@ void DirectRenderer::DrawRenderPass(DrawingFrame* frame,
|
| }
|
|
|
| const QuadList& quad_list = render_pass->quad_list;
|
| + ScopedPtrDeque<DrawPolygon> poly_list;
|
| +
|
| + int count = 0;
|
| + int last_context_id = 0;
|
| for (QuadList::ConstBackToFrontIterator it = quad_list.BackToFrontBegin();
|
| it != quad_list.BackToFrontEnd();
|
| ++it) {
|
| - const DrawQuad& quad = *(*it);
|
| - bool should_skip_quad = false;
|
| + DrawQuad& quad = *(*it);
|
| + gfx::QuadF send_quad(quad.visible_rect);
|
| + gfx::Transform quad_transform = quad.quadTransform();
|
| +
|
| + if (using_scissor_as_optimization) {
|
| + if (ShouldSkipQuad(quad, render_pass_scissor)) {
|
| + continue;
|
| + }
|
| + }
|
| + if (last_context_id != quad.shared_quad_state->sorting_context_id) {
|
| + last_context_id = quad.shared_quad_state->sorting_context_id;
|
| + FlushPolygons(&poly_list, frame,
|
| + render_pass_scissor, using_scissor_as_optimization);
|
| + }
|
| +
|
| + // This layer is in a 3D sorting context so we add it to the list of
|
| + // polygons to go into the BSP tree.
|
| + if (quad.shared_quad_state->sorting_context_id != 0) {
|
| + scoped_ptr<DrawPolygon> new_polygon(
|
| + new DrawPolygon(*it, quad.visible_rect, quad_transform, count++));
|
| + if (new_polygon->points().size() > 2u) {
|
| + poly_list.push_back(new_polygon.Pass());
|
| + }
|
| + continue;
|
| + }
|
|
|
| if (using_scissor_as_optimization) {
|
| SetScissorStateForQuadWithRenderPassScissor(
|
| - frame, quad, render_pass_scissor, &should_skip_quad);
|
| + frame, quad, render_pass_scissor);
|
| } else {
|
| SetScissorStateForQuad(frame, quad);
|
| }
|
| -
|
| - if (!should_skip_quad)
|
| - DoDrawQuad(frame, *it);
|
| + // Go ahead and draw the flat layers as normal and reset the draw mode
|
| + // flag to show that we're now drawing flat layers
|
| + DoDrawQuad(frame, *it);
|
| }
|
| + FlushPolygons(&poly_list, frame,
|
| + render_pass_scissor, using_scissor_as_optimization);
|
| FinishDrawingQuadList();
|
| }
|
|
|
|
|