void CCOverdrawMetrics::didDraw(const TransformationMatrix& transformToTarget, const IntRect& beforeCullRect, const IntRect& afterCullRect, const IntRect& opaqueRect) { float beforeCullArea = quadArea(transformToTarget.mapQuad(FloatQuad(beforeCullRect))); float afterCullArea = quadArea(transformToTarget.mapQuad(FloatQuad(afterCullRect))); float afterCullOpaqueArea = quadArea(transformToTarget.mapQuad(FloatQuad(intersection(opaqueRect, afterCullRect)))); m_pixelsDrawnOpaque += afterCullOpaqueArea; m_pixelsDrawnTranslucent += afterCullArea - afterCullOpaqueArea; m_pixelsCulled += beforeCullArea - afterCullArea; }
double cellVA(vtkUnstructuredGrid *grid, vtkIdType cellId, bool neg) { vtkIdType *pts; vtkIdType Npts; vec3_t p[8]; grid->GetCellPoints(cellId, Npts, pts); for (int i_pts = 0; i_pts < Npts; ++i_pts) { grid->GetPoints()->GetPoint(pts[i_pts], p[i_pts].data()); } vtkIdType cellType = grid->GetCellType(cellId); if (cellType == VTK_TRIANGLE) return triArea (p[0], p[1], p[2]); else if (cellType == VTK_QUAD) return quadArea(p[0], p[1], p[2], p[3]); else if (cellType == VTK_TETRA) return tetraVol(p[0], p[1], p[2], p[3], neg); else if (cellType == VTK_PYRAMID) return pyraVol (p[0], p[1], p[2], p[3], p[4], neg); else if (cellType == VTK_WEDGE) return prismVol(p[0], p[1], p[2], p[3], p[4], p[5], neg); else if (cellType == VTK_HEXAHEDRON) return hexaVol (p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], neg); return 0.0; }
void CCQuadCuller::cullOccludedQuads(CCQuadList& quadList, bool haveDamageRect, const FloatRect& damageRect, CCOverdrawCounts* overdrawMetrics) { if (!quadList.size()) return; CCQuadList culledList; culledList.reserveCapacity(quadList.size()); Region opaqueCoverageThusFar; for (int i = quadList.size() - 1; i >= 0; --i) { CCDrawQuad* drawQuad = quadList[i].get(); FloatRect floatTransformedRect = drawQuad->quadTransform().mapRect(FloatRect(drawQuad->quadRect())); if (haveDamageRect) floatTransformedRect.intersect(damageRect); // Inflate rect to be tested to stay conservative. IntRect transformedQuadRect(enclosingIntRect(floatTransformedRect)); IntRect transformedVisibleQuadRect = rectSubtractRegion(opaqueCoverageThusFar, transformedQuadRect); bool keepQuad = !transformedVisibleQuadRect.isEmpty(); // See if we can reduce the number of pixels to draw by reducing the size of the draw // quad - we do this by changing its visible rect. bool didReduceQuadSize = false; if (keepQuad) { if (transformedVisibleQuadRect != transformedQuadRect && drawQuad->isLayerAxisAlignedIntRect()) { drawQuad->setQuadVisibleRect(drawQuad->quadTransform().inverse().mapRect(transformedVisibleQuadRect)); didReduceQuadSize = true; } // When adding rect to opaque region, deflate it to stay conservative. if (drawQuad->isLayerAxisAlignedIntRect() && !drawQuad->opaqueRect().isEmpty()) { FloatRect floatOpaqueRect = drawQuad->quadTransform().mapRect(FloatRect(drawQuad->opaqueRect())); opaqueCoverageThusFar.unite(Region(enclosedIntRect(floatOpaqueRect))); } culledList.append(quadList[i].release()); } if (overdrawMetrics) { TRACE_EVENT("CCQuadCuller::cullOccludedQuads_OverdrawMetrics", 0, 0); // We compute the area of the transformed quad, as this should be in pixels. float area = quadArea(drawQuad->quadTransform().mapQuad(FloatQuad(drawQuad->quadRect()))); if (keepQuad) { if (didReduceQuadSize) { float visibleQuadRectArea = quadArea(drawQuad->quadTransform().mapQuad(FloatQuad(drawQuad->quadVisibleRect()))); overdrawMetrics->m_pixelsCulled += area - visibleQuadRectArea; area = visibleQuadRectArea; } IntRect visibleOpaqueRect(drawQuad->quadVisibleRect()); visibleOpaqueRect.intersect(drawQuad->opaqueRect()); FloatQuad visibleOpaqueQuad = drawQuad->quadTransform().mapQuad(FloatQuad(visibleOpaqueRect)); float opaqueArea = quadArea(visibleOpaqueQuad); overdrawMetrics->m_pixelsDrawnOpaque += opaqueArea; overdrawMetrics->m_pixelsDrawnTransparent += area - opaqueArea; } else overdrawMetrics->m_pixelsCulled += area; } } quadList.clear(); // Release anything that remains. culledList.reverse(); quadList.swap(culledList); }