Commit 1d801997 authored by enne@chromium.org's avatar enne@chromium.org

Revert of https://codereview.chromium.org/63443003/

Reason for revert: Caused a 30% rasterization regression

TBR=reveman@chromium.org,senorblanco@chromium.org,vangelis@google.com,reed@google.com
BUG=310796,332137

Review URL: https://codereview.chromium.org/126343003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@243466 0039d316-1c4b-4281-b951-d872f2087c98
parent ec4a71c1
......@@ -97,6 +97,8 @@ void RasterizeAndRecordBenchmarkImpl::RunOnLayer(PictureLayerImpl* layer) {
PicturePileImpl::Analysis analysis;
base::TimeTicks start = Now();
picture_pile->AnalyzeInRect(
content_rect, contents_scale, &analysis, NULL);
picture_pile->RasterToBitmap(&canvas, content_rect, contents_scale, NULL);
base::TimeTicks end = Now();
base::TimeDelta duration = end - start;
......
......@@ -47,6 +47,7 @@ ImplThreadRenderingStats::AsTraceableData() const {
void ImplThreadRenderingStats::Add(const ImplThreadRenderingStats& other) {
frame_count += other.frame_count;
rasterize_time += other.rasterize_time;
analysis_time += other.analysis_time;
rasterized_pixel_count += other.rasterized_pixel_count;
}
......@@ -61,8 +62,11 @@ void RenderingStats::EnumerateFields(Enumerator* enumerator) const {
main_stats.record_time.InSecondsF());
enumerator->AddInt64("recordedPixelCount",
main_stats.recorded_pixel_count);
// Combine rasterization and analysis time as a precursor to combining
// them in the same step internally.
enumerator->AddDouble("rasterizeTime",
impl_stats.rasterize_time.InSecondsF());
impl_stats.rasterize_time.InSecondsF() +
impl_stats.analysis_time.InSecondsF());
enumerator->AddInt64("rasterizedPixelCount",
impl_stats.rasterized_pixel_count);
}
......
......@@ -49,6 +49,7 @@ struct CC_EXPORT ImplThreadRenderingStats {
int64 frame_count;
base::TimeDelta rasterize_time;
base::TimeDelta analysis_time;
int64 rasterized_pixel_count;
ImplThreadRenderingStats();
......
......@@ -99,4 +99,13 @@ void RenderingStatsInstrumentation::AddRaster(base::TimeDelta duration,
impl_stats_.rasterized_pixel_count += pixels;
}
void RenderingStatsInstrumentation::AddAnalysis(base::TimeDelta duration,
int64 pixels) {
if (!record_rendering_stats_)
return;
base::AutoLock scoped_lock(lock_);
impl_stats_.analysis_time += duration;
}
} // namespace cc
......@@ -52,6 +52,7 @@ class CC_EXPORT RenderingStatsInstrumentation {
void AddPaint(base::TimeDelta duration, int64 pixels);
void AddRecord(base::TimeDelta duration, int64 pixels);
void AddRaster(base::TimeDelta duration, int64 pixels);
void AddAnalysis(base::TimeDelta duration, int64 pixels);
protected:
RenderingStatsInstrumentation();
......
......@@ -298,6 +298,7 @@ void Picture::GatherPixelRefs(
int Picture::Raster(
SkCanvas* canvas,
SkDrawPictureCallback* callback,
const Region& negated_content_region,
float contents_scale) {
TRACE_EVENT_BEGIN1(
......@@ -315,7 +316,7 @@ int Picture::Raster(
canvas->scale(contents_scale, contents_scale);
canvas->translate(layer_rect_.x(), layer_rect_.y());
picture_->draw(canvas);
picture_->draw(canvas, callback);
SkIRect bounds;
canvas->getClipDeviceBounds(&bounds);
canvas->restore();
......
......@@ -71,6 +71,7 @@ class CC_EXPORT Picture
// Apply this scale and raster the negated region into the canvas. See comment
// in PicturePileImpl::RasterCommon for explanation on negated content region.
int Raster(SkCanvas* canvas,
SkDrawPictureCallback* callback,
const Region& negated_content_region,
float contents_scale);
......
......@@ -74,9 +74,20 @@ void PicturePileImpl::RasterDirect(
float contents_scale,
RenderingStatsInstrumentation* rendering_stats_instrumentation) {
RasterCommon(canvas,
NULL,
canvas_rect,
contents_scale,
rendering_stats_instrumentation);
rendering_stats_instrumentation,
false);
}
void PicturePileImpl::RasterForAnalysis(
skia::AnalysisCanvas* canvas,
gfx::Rect canvas_rect,
float contents_scale,
RenderingStatsInstrumentation* stats_instrumentation) {
RasterCommon(
canvas, canvas, canvas_rect, contents_scale, stats_instrumentation, true);
}
void PicturePileImpl::RasterToBitmap(
......@@ -127,9 +138,11 @@ void PicturePileImpl::RasterToBitmap(
}
RasterCommon(canvas,
NULL,
canvas_rect,
contents_scale,
rendering_stats_instrumentation);
rendering_stats_instrumentation,
false);
}
void PicturePileImpl::CoalesceRasters(gfx::Rect canvas_rect,
......@@ -193,9 +206,11 @@ void PicturePileImpl::CoalesceRasters(gfx::Rect canvas_rect,
void PicturePileImpl::RasterCommon(
SkCanvas* canvas,
SkDrawPictureCallback* callback,
gfx::Rect canvas_rect,
float contents_scale,
RenderingStatsInstrumentation* rendering_stats_instrumentation) {
RenderingStatsInstrumentation* rendering_stats_instrumentation,
bool is_analysis) {
DCHECK(contents_scale >= min_contents_scale_);
canvas->translate(-canvas_rect.x(), -canvas_rect.y());
......@@ -241,7 +256,7 @@ void PicturePileImpl::RasterCommon(
start_time = rendering_stats_instrumentation->StartRecording();
rasterized_pixel_count = picture->Raster(
canvas, negated_clip_region, contents_scale);
canvas, callback, negated_clip_region, contents_scale);
if (rendering_stats_instrumentation) {
base::TimeDelta duration =
......@@ -251,10 +266,15 @@ void PicturePileImpl::RasterCommon(
}
if (rendering_stats_instrumentation) {
if (is_analysis) {
rendering_stats_instrumentation->AddAnalysis(best_duration,
rasterized_pixel_count);
} else {
rendering_stats_instrumentation->AddRaster(best_duration,
rasterized_pixel_count);
}
}
}
#ifndef NDEBUG
// Fill the clip with debug color. This allows us to
......@@ -288,6 +308,39 @@ skia::RefPtr<SkPicture> PicturePileImpl::GetFlattenedPicture() {
return picture;
}
void PicturePileImpl::AnalyzeInRect(
gfx::Rect content_rect,
float contents_scale,
PicturePileImpl::Analysis* analysis) {
AnalyzeInRect(content_rect, contents_scale, analysis, NULL);
}
void PicturePileImpl::AnalyzeInRect(
gfx::Rect content_rect,
float contents_scale,
PicturePileImpl::Analysis* analysis,
RenderingStatsInstrumentation* stats_instrumentation) {
DCHECK(analysis);
TRACE_EVENT0("cc", "PicturePileImpl::AnalyzeInRect");
gfx::Rect layer_rect = gfx::ScaleToEnclosingRect(
content_rect, 1.0f / contents_scale);
layer_rect.Intersect(gfx::Rect(tiling_.total_size()));
SkBitmap empty_bitmap;
empty_bitmap.setConfig(SkBitmap::kNo_Config,
layer_rect.width(),
layer_rect.height());
skia::AnalysisDevice device(empty_bitmap);
skia::AnalysisCanvas canvas(&device);
RasterForAnalysis(&canvas, layer_rect, 1.0f, stats_instrumentation);
analysis->is_solid_color = canvas.GetColorIfSolid(&analysis->solid_color);
analysis->has_text = canvas.HasText();
}
PicturePileImpl::Analysis::Analysis()
: is_solid_color(false),
has_text(false) {
......@@ -344,19 +397,6 @@ void PicturePileImpl::PixelRefIterator::AdvanceToTilePictureWithPixelRefs() {
}
}
gfx::Rect PicturePileImpl::AnalysisRectForRaster(gfx::Rect content_rect,
float contents_scale) const {
// Bound the analysis rect to just the pile content.
gfx::Rect content_bounds(
gfx::ScaleToEnclosingRect(gfx::Rect(size()), contents_scale));
gfx::Rect analysis_rect(content_rect);
analysis_rect.Intersect(content_bounds);
// Move to canvas space.
analysis_rect.set_origin(gfx::Point());
return analysis_rect;
}
void PicturePileImpl::DidBeginTracing() {
gfx::Rect layer_rect(tiling_.total_size());
std::set<void*> processed_pictures;
......
......@@ -52,6 +52,14 @@ class CC_EXPORT PicturePileImpl : public PicturePileBase {
float contents_scale,
RenderingStatsInstrumentation* stats_instrumentation);
// Called when analyzing a tile. We can use AnalysisCanvas as
// SkDrawPictureCallback, which allows us to early out from analysis.
void RasterForAnalysis(
skia::AnalysisCanvas* canvas,
gfx::Rect canvas_rect,
float contents_scale,
RenderingStatsInstrumentation* stats_instrumentation);
skia::RefPtr<SkPicture> GetFlattenedPicture();
struct CC_EXPORT Analysis {
......@@ -63,6 +71,15 @@ class CC_EXPORT PicturePileImpl : public PicturePileBase {
SkColor solid_color;
};
void AnalyzeInRect(gfx::Rect content_rect,
float contents_scale,
Analysis* analysis);
void AnalyzeInRect(gfx::Rect content_rect,
float contents_scale,
Analysis* analysis,
RenderingStatsInstrumentation* stats_instrumentation);
class CC_EXPORT PixelRefIterator {
public:
PixelRefIterator(gfx::Rect content_rect,
......@@ -85,9 +102,6 @@ class CC_EXPORT PicturePileImpl : public PicturePileBase {
std::set<const void*> processed_pictures_;
};
gfx::Rect AnalysisRectForRaster(gfx::Rect content_rect,
float contents_scale) const;
void DidBeginTracing();
protected:
......@@ -122,9 +136,11 @@ class CC_EXPORT PicturePileImpl : public PicturePileBase {
void RasterCommon(
SkCanvas* canvas,
SkDrawPictureCallback* callback,
gfx::Rect canvas_rect,
float contents_scale,
RenderingStatsInstrumentation* rendering_stats_instrumentation);
RenderingStatsInstrumentation* rendering_stats_instrumentation,
bool is_analysis);
// Once instantiated, |clones_for_drawing_| can't be modified. This
// guarantees thread-safe access during the life time of a PicturePileImpl
......
......@@ -13,8 +13,6 @@
#include "skia/ext/lazy_pixel_ref.h"
#include "skia/ext/paint_simplifier.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/utils/SkNWayCanvas.h"
#include "ui/gfx/skia_util.h"
namespace cc {
......@@ -33,6 +31,10 @@ class IdentityAllocator : public SkBitmap::Allocator {
void* buffer_;
};
// Flag to indicate whether we should try and detect that
// a tile is of solid color.
const bool kUseColorEstimator = true;
class DisableLCDTextFilter : public SkDrawFilter {
public:
// SkDrawFilter interface.
......@@ -71,11 +73,35 @@ class RasterWorkerPoolTaskImpl : public internal::RasterWorkerPoolTask {
rendering_stats_(rendering_stats),
reply_(reply) {}
// Overridden from internal::RasterWorkerPoolTask:
virtual bool RunOnWorkerThread(unsigned thread_index,
void RunAnalysisOnThread(unsigned thread_index) {
TRACE_EVENT1("cc",
"RasterWorkerPoolTaskImpl::RunAnalysisOnThread",
"data",
TracedValue::FromValue(DataAsValue().release()));
DCHECK(picture_pile_.get());
DCHECK(rendering_stats_);
PicturePileImpl* picture_clone =
picture_pile_->GetCloneForDrawingOnThread(thread_index);
DCHECK(picture_clone);
picture_clone->AnalyzeInRect(
content_rect_, contents_scale_, &analysis_, rendering_stats_);
// Record the solid color prediction.
UMA_HISTOGRAM_BOOLEAN("Renderer4.SolidColorTilesAnalyzed",
analysis_.is_solid_color);
// Clear the flag if we're not using the estimator.
analysis_.is_solid_color &= kUseColorEstimator;
}
bool RunRasterOnThread(unsigned thread_index,
void* buffer,
gfx::Size size,
int stride) OVERRIDE {
int stride) {
TRACE_EVENT2(
"cc", "RasterWorkerPoolTaskImpl::RunRasterOnThread",
"data",
......@@ -89,6 +115,9 @@ class RasterWorkerPoolTaskImpl : public internal::RasterWorkerPoolTask {
DCHECK(picture_pile_.get());
DCHECK(buffer);
if (analysis_.is_solid_color)
return false;
PicturePileImpl* picture_clone =
picture_pile_->GetCloneForDrawingOnThread(thread_index);
......@@ -117,22 +146,8 @@ class RasterWorkerPoolTaskImpl : public internal::RasterWorkerPoolTask {
break;
}
SkBitmap empty_bitmap;
empty_bitmap.setConfig(
SkBitmap::kNo_Config, content_rect_.width(), content_rect_.height());
gfx::Rect analysis_rect(
picture_clone->AnalysisRectForRaster(content_rect_, contents_scale_));
skia::AnalysisDevice analysis_device(empty_bitmap,
gfx::RectToSkRect(analysis_rect));
skia::AnalysisCanvas analysis_canvas(&analysis_device);
SkBitmapDevice raster_device(bitmap);
SkCanvas raster_canvas(&raster_device);
SkNWayCanvas canvas(content_rect_.width(), content_rect_.height());
canvas.addCanvas(&analysis_canvas);
canvas.addCanvas(&raster_canvas);
SkBitmapDevice device(bitmap);
SkCanvas canvas(&device);
skia::RefPtr<SkDrawFilter> draw_filter;
switch (raster_mode_) {
case LOW_QUALITY_RASTER_MODE:
......@@ -178,17 +193,18 @@ class RasterWorkerPoolTaskImpl : public internal::RasterWorkerPoolTask {
ChangeBitmapConfigIfNeeded(bitmap, buffer);
analysis_.is_solid_color =
analysis_canvas.GetColorIfSolid(&analysis_.solid_color);
analysis_.has_text = analysis_canvas.HasText();
// Record the solid color prediction.
UMA_HISTOGRAM_BOOLEAN("Renderer4.SolidColorTilesAnalyzed",
analysis_.is_solid_color);
return !analysis_.is_solid_color;
return true;
}
// Overridden from internal::RasterWorkerPoolTask:
virtual bool RunOnWorkerThread(unsigned thread_index,
void* buffer,
gfx::Size size,
int stride)
OVERRIDE {
RunAnalysisOnThread(thread_index);
return RunRasterOnThread(thread_index, buffer, size, stride);
}
virtual void CompleteOnOriginThread() OVERRIDE {
reply_.Run(analysis_, !HasFinishedRunning() || WasCanceled());
}
......
......@@ -9,7 +9,6 @@
#include "cc/test/impl_side_painting_settings.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/skia_util.h"
namespace cc {
......@@ -108,26 +107,4 @@ void FakePicturePileImpl::RerecordPile() {
}
}
void FakePicturePileImpl::AnalyzeInRect(gfx::Rect content_rect,
float contents_scale,
Analysis* analysis) {
// Create and raster to a bitmap of content_rect size, even though the
// analysis_rect may be smaller to simulate edge tiles where recorded content
// doesn't cover the entire content_rect.
SkBitmap empty_bitmap;
empty_bitmap.setConfig(SkBitmap::kNo_Config,
content_rect.width(),
content_rect.height());
gfx::Rect analysis_rect(
AnalysisRectForRaster(content_rect, contents_scale));
skia::AnalysisDevice device(empty_bitmap, gfx::RectToSkRect(analysis_rect));
skia::AnalysisCanvas canvas(&device);
RasterDirect(&canvas, content_rect, contents_scale, NULL);
analysis->is_solid_color = canvas.GetColorIfSolid(&analysis->solid_color);
analysis->has_text = canvas.HasText();
}
} // namespace cc
......@@ -34,10 +34,6 @@ class FakePicturePileImpl : public PicturePileImpl {
void RemoveRecordingAt(int x, int y);
void RerecordPile();
void AnalyzeInRect(gfx::Rect content_rect,
float contents_scale,
Analysis* analysis);
void add_draw_rect(const gfx::RectF& rect) {
client_.add_draw_rect(rect, default_paint_);
}
......
......@@ -69,7 +69,7 @@ void DrawPicture(unsigned char* buffer,
SkBitmapDevice device(bitmap);
SkCanvas canvas(&device);
canvas.clipRect(gfx::RectToSkRect(layer_rect));
picture->Raster(&canvas, layer_rect, 1.0f);
picture->Raster(&canvas, NULL, layer_rect, 1.0f);
}
void CreateBitmap(gfx::Size size, const char* uri, SkBitmap* bitmap) {
......
......@@ -10,6 +10,7 @@
#include "third_party/skia/include/core/SkRRect.h"
#include "third_party/skia/include/core/SkShader.h"
#include "third_party/skia/src/core/SkRasterClip.h"
#include "ui/gfx/rect_conversions.h"
namespace {
......@@ -69,18 +70,8 @@ bool IsFullQuad(const SkDraw& draw,
namespace skia {
AnalysisDevice::AnalysisDevice(const SkBitmap& bitmap, SkRect analysis_rect)
: INHERITED(bitmap),
analysis_rect_(analysis_rect),
is_forced_not_solid_(false),
is_forced_not_transparent_(false),
is_solid_color_(true),
is_transparent_(true),
has_text_(false) {}
AnalysisDevice::AnalysisDevice(const SkBitmap& bitmap)
: INHERITED(bitmap),
analysis_rect_(SkRect::MakeWH(bitmap.width(), bitmap.height())),
is_forced_not_solid_(false),
is_forced_not_transparent_(false),
is_solid_color_(true),
......@@ -146,13 +137,8 @@ void AnalysisDevice::drawPoints(const SkDraw& draw,
void AnalysisDevice::drawRect(const SkDraw& draw,
const SkRect& rect,
const SkPaint& paint) {
// Early out of work where possible. It could be the case that a picture
// draws text and then clears, but this is unlikely.
if (has_text_ && !is_solid_color_)
return;
bool does_cover_canvas =
IsFullQuad(draw, analysis_rect_, rect);
IsFullQuad(draw, SkRect::MakeWH(width(), height()), rect);
SkXfermode::Mode xfermode;
SkXfermode::AsMode(paint.getXfermode(), &xfermode);
......@@ -293,7 +279,7 @@ void AnalysisDevice::drawPosTextOnPath(const SkDraw& draw,
#endif
void AnalysisDevice::drawVertices(const SkDraw& draw,
SkCanvas::VertexMode mode,
SkCanvas::VertexMode,
int vertex_count,
const SkPoint verts[],
const SkPoint texs[],
......@@ -331,6 +317,11 @@ bool AnalysisCanvas::HasText() const {
return (static_cast<AnalysisDevice*>(getDevice()))->HasText();
}
bool AnalysisCanvas::abortDrawing() {
// Early out as soon as we have detected that the tile has text.
return HasText();
}
bool AnalysisCanvas::clipRect(const SkRect& rect, SkRegion::Op op, bool do_aa) {
return INHERITED::clipRect(rect, op, do_aa);
}
......@@ -382,10 +373,9 @@ int AnalysisCanvas::saveLayer(const SkRect* bounds,
// If after we draw to the saved layer, we have to blend with the current
// layer, then we can conservatively say that the canvas will not be of
// solid color.
SkRect analysis_rect =
static_cast<AnalysisDevice*>(getDevice())->AnalysisRect();
if ((paint && !IsSolidColorPaint(*paint)) ||
(bounds && !bounds->contains(analysis_rect))) {
(bounds && !bounds->contains(SkRect::MakeWH(getDevice()->width(),
getDevice()->height())))) {
if (force_not_solid_stack_level_ == kNoLayer) {
force_not_solid_stack_level_ = saved_stack_size_;
(static_cast<AnalysisDevice*>(getDevice()))->SetForceNotSolid(true);
......
......@@ -20,15 +20,18 @@ class AnalysisDevice;
// To use: create a SkBitmap with kNo_Config, create an AnalysisDevice
// using that bitmap, and create an AnalysisCanvas using the device.
// Play a picture into the canvas, and then check result.
class SK_API AnalysisCanvas : public SkCanvas {
class SK_API AnalysisCanvas : public SkCanvas, public SkDrawPictureCallback {
public:
explicit AnalysisCanvas(AnalysisDevice* device);
AnalysisCanvas(AnalysisDevice*);
virtual ~AnalysisCanvas();
// Returns true when a SkColor can be used to represent result.
bool GetColorIfSolid(SkColor* color) const;
bool HasText() const;
// SkDrawPictureCallback override.
virtual bool abortDrawing() OVERRIDE;
// SkCanvas overrides.
virtual bool clipRect(const SkRect& rect,
SkRegion::Op op = SkRegion::kIntersect_Op,
......@@ -60,9 +63,6 @@ class SK_API AnalysisCanvas : public SkCanvas {
// to be derived from SkBaseDevice (rather than SkBitmapDevice)
class SK_API AnalysisDevice : public SkBitmapDevice {
public:
// |analysis_rect| is in device space.
AnalysisDevice(const SkBitmap& bitmap, SkRect analysis_rect);
// Analyze the entire bitmap.
AnalysisDevice(const SkBitmap& bitmap);
virtual ~AnalysisDevice();
......@@ -72,8 +72,6 @@ class SK_API AnalysisDevice : public SkBitmapDevice {
void SetForceNotSolid(bool flag);
void SetForceNotTransparent(bool flag);
SkRect AnalysisRect() const { return analysis_rect_; }
protected:
// SkBaseDevice overrides.
virtual void clear(SkColor color) OVERRIDE;
......@@ -159,7 +157,6 @@ class SK_API AnalysisDevice : public SkBitmapDevice {
private:
typedef SkBitmapDevice INHERITED;
SkRect analysis_rect_;
bool is_forced_not_solid_;
bool is_forced_not_transparent_;
bool is_solid_color_;
......
......@@ -18,7 +18,6 @@ void TransparentFill(skia::AnalysisCanvas& canvas) {
}
} // namespace
namespace skia {
TEST(AnalysisCanvasTest, EmptyCanvas) {
......@@ -342,6 +341,15 @@ TEST(AnalysisCanvasTest, HasText) {
canvas.drawTextOnPath(text, byteLength, path, NULL, paint);
EXPECT_TRUE(canvas.HasText());
}
{
// Text under opaque rect.
skia::AnalysisDevice device(bitmap);
skia::AnalysisCanvas canvas(&device);
canvas.drawText(text, byteLength, point.fX, point.fY, paint);
EXPECT_TRUE(canvas.HasText());
canvas.drawRect(SkRect::MakeWH(width, height), paint);
EXPECT_FALSE(canvas.HasText());
}
{
// Text under translucent rect.
skia::AnalysisDevice device(bitmap);
......@@ -353,6 +361,17 @@ TEST(AnalysisCanvasTest, HasText) {
canvas.drawRect(SkRect::MakeWH(width, height), translucentPaint);
EXPECT_TRUE(canvas.HasText());
}
{
// Text under rect in clear mode.
skia::AnalysisDevice device(bitmap);
skia::AnalysisCanvas canvas(&device);
canvas.drawText(text, byteLength, point.fX, point.fY, paint);
EXPECT_TRUE(canvas.HasText());
SkPaint clearModePaint;
clearModePaint.setXfermodeMode(SkXfermode::kClear_Mode);
canvas.drawRect(SkRect::MakeWH(width, height), clearModePaint);
EXPECT_FALSE(canvas.HasText());
}
{
// Clear.
skia::AnalysisDevice device(bitmap);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment