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(); |
} |