#include "base/debug/trace_event.h"
#include "cc/output/context_provider.h"
#include "cc/resources/raster_buffer.h"
+#include "cc/resources/raster_source.h"
#include "cc/resources/resource.h"
#include "cc/resources/resource_provider.h"
#include "cc/resources/scoped_gpu_raster.h"
#include "third_party/skia/include/core/SkPictureRecorder.h"
#include "third_party/skia/include/core/SkSurface.h"
#include "third_party/skia/include/gpu/GrContext.h"
-#include "third_party/skia/include/utils/SkNullCanvas.h"
namespace cc {
namespace {
public:
RasterBufferImpl(ResourceProvider* resource_provider,
const Resource* resource,
- SkMultiPictureDraw* multi_picture_draw)
- : resource_provider_(resource_provider),
+ SkMultiPictureDraw* multi_picture_draw,
+ bool use_distance_field_text)
+ : lock_(resource_provider, resource->id()),
resource_(resource),
- surface_(resource_provider->LockForWriteToSkSurface(resource->id())),
- multi_picture_draw_(multi_picture_draw) {}
- virtual ~RasterBufferImpl() {
- resource_provider_->UnlockForWriteToSkSurface(resource_->id());
- }
+ multi_picture_draw_(multi_picture_draw),
+ use_distance_field_text_(use_distance_field_text) {}
// Overridden from RasterBuffer:
- virtual skia::RefPtr<SkCanvas> AcquireSkCanvas() OVERRIDE {
- if (!surface_)
- return skia::AdoptRef(SkCreateNullCanvas());
+ void Playback(const RasterSource* raster_source,
+ const gfx::Rect& rect,
+ float scale) override {
+ // Turn on distance fields for layers that have ever animated.
+ bool use_distance_field_text =
+ use_distance_field_text_ ||
+ raster_source->SuitableForDistanceFieldText();
+ SkSurface* sk_surface = lock_.GetSkSurface(use_distance_field_text);
+
+ if (!sk_surface)
+ return;
- skia::RefPtr<SkCanvas> canvas = skia::SharePtr(recorder_.beginRecording(
- resource_->size().width(), resource_->size().height()));
+ SkPictureRecorder recorder;
+ gfx::Size size = resource_->size();
+ skia::RefPtr<SkCanvas> canvas =
+ skia::SharePtr(recorder.beginRecording(size.width(), size.height()));
- // Balanced with restore() call in ReleaseSkCanvas. save()/restore() calls
- // are needed to ensure that canvas returns to its previous state after use.
canvas->save();
- return canvas;
- }
- virtual void ReleaseSkCanvas(const skia::RefPtr<SkCanvas>& canvas) OVERRIDE {
- if (!surface_)
- return;
-
- // Balanced with save() call in AcquireSkCanvas.
+ raster_source->PlaybackToCanvas(canvas.get(), rect, scale);
canvas->restore();
// Add the canvas and recorded picture to |multi_picture_draw_|.
- skia::RefPtr<SkPicture> picture = skia::AdoptRef(recorder_.endRecording());
- multi_picture_draw_->add(surface_->getCanvas(), picture.get());
+ skia::RefPtr<SkPicture> picture = skia::AdoptRef(recorder.endRecording());
+ multi_picture_draw_->add(sk_surface->getCanvas(), picture.get());
}
private:
- ResourceProvider* resource_provider_;
+ ResourceProvider::ScopedWriteLockGr lock_;
const Resource* resource_;
- SkSurface* surface_;
SkMultiPictureDraw* multi_picture_draw_;
- SkPictureRecorder recorder_;
+ bool use_distance_field_text_;
DISALLOW_COPY_AND_ASSIGN(RasterBufferImpl);
};
scoped_ptr<RasterWorkerPool> GpuRasterWorkerPool::Create(
base::SequencedTaskRunner* task_runner,
ContextProvider* context_provider,
- ResourceProvider* resource_provider) {
- return make_scoped_ptr<RasterWorkerPool>(new GpuRasterWorkerPool(
- task_runner, context_provider, resource_provider));
+ ResourceProvider* resource_provider,
+ bool use_distance_field_text) {
+ return make_scoped_ptr<RasterWorkerPool>(
+ new GpuRasterWorkerPool(task_runner,
+ context_provider,
+ resource_provider,
+ use_distance_field_text));
}
GpuRasterWorkerPool::GpuRasterWorkerPool(base::SequencedTaskRunner* task_runner,
ContextProvider* context_provider,
- ResourceProvider* resource_provider)
+ ResourceProvider* resource_provider,
+ bool use_distance_field_text)
: task_runner_(task_runner),
task_graph_runner_(new TaskGraphRunner),
namespace_token_(task_graph_runner_->GetNamespaceToken()),
context_provider_(context_provider),
resource_provider_(resource_provider),
run_tasks_on_origin_thread_pending_(false),
+ use_distance_field_text_(use_distance_field_text),
raster_finished_weak_ptr_factory_(this),
weak_ptr_factory_(this) {
DCHECK(context_provider_);
scoped_ptr<RasterBuffer> GpuRasterWorkerPool::AcquireBufferForRaster(
const Resource* resource) {
- // RasterBuffer implementation depends on a SkSurface having been acquired for
- // the resource.
- resource_provider_->AcquireSkSurface(resource->id());
-
return make_scoped_ptr<RasterBuffer>(
- new RasterBufferImpl(resource_provider_, resource, &multi_picture_draw_));
+ new RasterBufferImpl(resource_provider_,
+ resource,
+ &multi_picture_draw_,
+ use_distance_field_text_));
}
void GpuRasterWorkerPool::ReleaseBufferForRaster(