| Index: src/gpu/GrPictureUtils.cpp
|
| ===================================================================
|
| --- src/gpu/GrPictureUtils.cpp (revision 0)
|
| +++ src/gpu/GrPictureUtils.cpp (revision 0)
|
| @@ -0,0 +1,247 @@
|
| +/*
|
| + * Copyright 2014 Google Inc.
|
| + *
|
| + * Use of this source code is governed by a BSD-style license that can be
|
| + * found in the LICENSE file.
|
| + */
|
| +
|
| +#include "GrPictureUtils.h"
|
| +#include "SkDevice.h"
|
| +
|
| +// The GrGather device performs GPU-backend-specific preprocessing on
|
| +// a picture. The results are stored in a GPUAccelData.
|
| +//
|
| +// Currently the only interesting work is done in drawDevice (i.e., when a
|
| +// saveLayer is collapsed back into its parent) and, maybe, in onCreateDevice.
|
| +// All the current work could be done much more efficiently by just traversing the
|
| +// raw op codes in the SkPicture (although we would still need to replay all the
|
| +// clip calls).
|
| +class GrGatherDevice : public SkBaseDevice {
|
| +public:
|
| + SK_DECLARE_INST_COUNT(GrGatherDevice)
|
| +
|
| + GrGatherDevice(int width, int height, SkPicture* picture, GPUAccelData* accelData) {
|
| + fPicture = picture;
|
| + fInfo.fSize.set(width, height);
|
| + fInfo.fSaveLayerOpID = fPicture->EXPERIMENTAL_curOpID();
|
| + fInfo.fRestoreOpID = 0;
|
| + fInfo.fHasNestedLayers = false;
|
| +
|
| + fEmptyBitmap.setConfig(SkImageInfo::Make(fInfo.fSize.fWidth,
|
| + fInfo.fSize.fHeight,
|
| + kUnknown_SkColorType,
|
| + kIgnore_SkAlphaType));
|
| + fAccelData = accelData;
|
| + fAlreadyDrawn = false;
|
| + }
|
| +
|
| + virtual ~GrGatherDevice() { }
|
| +
|
| + virtual int width() const SK_OVERRIDE { return fInfo.fSize.width(); }
|
| + virtual int height() const SK_OVERRIDE { return fInfo.fSize.height(); }
|
| + virtual bool isOpaque() const SK_OVERRIDE { return false; }
|
| + virtual SkBitmap::Config config() const SK_OVERRIDE {
|
| + return SkBitmap::kNo_Config;
|
| + }
|
| + virtual SkImageInfo imageInfo() const SK_OVERRIDE {
|
| + return fEmptyBitmap.info();
|
| + }
|
| +
|
| +#ifdef SK_SUPPORT_LEGACY_WRITEPIXELSCONFIG
|
| + virtual void writePixels(const SkBitmap& bitmap, int x, int y,
|
| + SkCanvas::Config8888 config8888) SK_OVERRIDE {
|
| + NotSupported();
|
| + }
|
| +#endif
|
| + virtual GrRenderTarget* accessRenderTarget() SK_OVERRIDE { return NULL; }
|
| +
|
| +protected:
|
| + virtual bool filterTextFlags(const SkPaint& paint, TextFlags*) SK_OVERRIDE {
|
| + return false;
|
| + }
|
| + virtual void clear(SkColor color) SK_OVERRIDE {
|
| + NothingToDo();
|
| + }
|
| + virtual void drawPaint(const SkDraw& draw, const SkPaint& paint) SK_OVERRIDE {
|
| + }
|
| + virtual void drawPoints(const SkDraw& draw, SkCanvas::PointMode mode, size_t count,
|
| + const SkPoint points[], const SkPaint& paint) SK_OVERRIDE {
|
| + }
|
| + virtual void drawRect(const SkDraw& draw, const SkRect& rect,
|
| + const SkPaint& paint) SK_OVERRIDE {
|
| + }
|
| + virtual void drawOval(const SkDraw& draw, const SkRect& rect,
|
| + const SkPaint& paint) SK_OVERRIDE {
|
| + }
|
| + virtual void drawRRect(const SkDraw& draw, const SkRRect& rrect,
|
| + const SkPaint& paint) SK_OVERRIDE {
|
| + }
|
| + virtual void drawPath(const SkDraw& draw, const SkPath& path,
|
| + const SkPaint& paint, const SkMatrix* prePathMatrix,
|
| + bool pathIsMutable) SK_OVERRIDE {
|
| + }
|
| + virtual void drawBitmap(const SkDraw& draw, const SkBitmap& bitmap,
|
| + const SkMatrix& matrix, const SkPaint& paint) SK_OVERRIDE {
|
| + }
|
| + virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap,
|
| + int x, int y, const SkPaint& paint) SK_OVERRIDE {
|
| + }
|
| + virtual void drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap,
|
| + const SkRect* srcOrNull, const SkRect& dst,
|
| + const SkPaint& paint,
|
| + SkCanvas::DrawBitmapRectFlags flags) SK_OVERRIDE {
|
| + }
|
| + virtual void drawText(const SkDraw& draw, const void* text, size_t len,
|
| + SkScalar x, SkScalar y,
|
| + const SkPaint& paint) SK_OVERRIDE {
|
| + }
|
| + virtual void drawPosText(const SkDraw& draw, const void* text, size_t len,
|
| + const SkScalar pos[], SkScalar constY,
|
| + int scalarsPerPos, const SkPaint& paint) SK_OVERRIDE {
|
| + }
|
| + virtual void drawTextOnPath(const SkDraw& draw, const void* text, size_t len,
|
| + const SkPath& path, const SkMatrix* matrix,
|
| + const SkPaint& paint) SK_OVERRIDE {
|
| + }
|
| + virtual void drawVertices(const SkDraw& draw, SkCanvas::VertexMode, int vertexCount,
|
| + const SkPoint verts[], const SkPoint texs[],
|
| + const SkColor colors[], SkXfermode* xmode,
|
| + const uint16_t indices[], int indexCount,
|
| + const SkPaint& paint) SK_OVERRIDE {
|
| + }
|
| + virtual void drawDevice(const SkDraw& draw, SkBaseDevice* deviceIn, int x, int y,
|
| + const SkPaint&) SK_OVERRIDE {
|
| + GrGatherDevice* device = static_cast<GrGatherDevice*>(deviceIn);
|
| +
|
| + if (device->fAlreadyDrawn) {
|
| + return;
|
| + }
|
| +
|
| + device->fInfo.fRestoreOpID = fPicture->EXPERIMENTAL_curOpID();
|
| + fAccelData->addSaveLayerInfo(device->fInfo);
|
| + device->fAlreadyDrawn = true;
|
| + }
|
| + // TODO: allow this call to return failure, or move to SkBitmapDevice only.
|
| + virtual const SkBitmap& onAccessBitmap() SK_OVERRIDE {
|
| + return fEmptyBitmap;
|
| + }
|
| +#ifdef SK_SUPPORT_LEGACY_READPIXELSCONFIG
|
| + virtual bool onReadPixels(const SkBitmap& bitmap,
|
| + int x, int y,
|
| + SkCanvas::Config8888 config8888) SK_OVERRIDE {
|
| + NotSupported();
|
| + return false;
|
| + }
|
| +#endif
|
| + virtual void lockPixels() SK_OVERRIDE { NothingToDo(); }
|
| + virtual void unlockPixels() SK_OVERRIDE { NothingToDo(); }
|
| + virtual bool allowImageFilter(const SkImageFilter*) SK_OVERRIDE { return false; }
|
| + virtual bool canHandleImageFilter(const SkImageFilter*) SK_OVERRIDE { return false; }
|
| + virtual bool filterImage(const SkImageFilter*, const SkBitmap&, const SkImageFilter::Context&,
|
| + SkBitmap* result, SkIPoint* offset) SK_OVERRIDE {
|
| + return false;
|
| + }
|
| +
|
| +private:
|
| + // The picture being processed
|
| + SkPicture *fPicture;
|
| +
|
| + SkBitmap fEmptyBitmap; // legacy -- need to remove
|
| +
|
| + // All information gathered during the gather process is stored here
|
| + GPUAccelData* fAccelData;
|
| +
|
| + // true if this device has already been drawn back to its parent(s) at least
|
| + // once.
|
| + bool fAlreadyDrawn;
|
| +
|
| + // The information regarding the saveLayer call this device represents.
|
| + GPUAccelData::SaveLayerInfo fInfo;
|
| +
|
| + virtual void replaceBitmapBackendForRasterSurface(const SkBitmap&) SK_OVERRIDE {
|
| + NotSupported();
|
| + }
|
| +
|
| + virtual SkBaseDevice* onCreateDevice(const SkImageInfo& info, Usage usage) SK_OVERRIDE {
|
| + // we expect to only get called via savelayer, in which case it is fine.
|
| + SkASSERT(kSaveLayer_Usage == usage);
|
| +
|
| + fInfo.fHasNestedLayers = true;
|
| + return SkNEW_ARGS(GrGatherDevice, (info.width(), info.height(), fPicture, fAccelData));
|
| + }
|
| +
|
| + virtual void flush() SK_OVERRIDE {}
|
| +
|
| + static void NotSupported() {
|
| + SkDEBUGFAIL("this method should never be called");
|
| + }
|
| +
|
| + static void NothingToDo() {}
|
| +
|
| + typedef SkBaseDevice INHERITED;
|
| +};
|
| +
|
| +// The GrGatherCanvas allows saveLayers but simplifies clipping. It is really
|
| +// only intended to be used as:
|
| +//
|
| +// GrGatherDevice dev(w, h, picture, accelData);
|
| +// GrGatherCanvas canvas(..., picture);
|
| +// canvas.gather();
|
| +//
|
| +// which is all just to fill in 'accelData'
|
| +class SK_API GrGatherCanvas : public SkCanvas {
|
| +public:
|
| + GrGatherCanvas(GrGatherDevice* device, SkPicture* pict)
|
| + : INHERITED(device)
|
| + , fPicture(pict) {
|
| + }
|
| +
|
| + void gather() {
|
| + if (NULL == fPicture || 0 == fPicture->width() || 0 == fPicture->height()) {
|
| + return;
|
| + }
|
| +
|
| + this->clipRect(SkRect::MakeWH(SkIntToScalar(fPicture->width()),
|
| + SkIntToScalar(fPicture->height())),
|
| + SkRegion::kIntersect_Op, false);
|
| + this->drawPicture(*fPicture);
|
| + }
|
| +
|
| + virtual void drawPicture(SkPicture& picture) SK_OVERRIDE {
|
| + picture.draw(this);
|
| + }
|
| +protected:
|
| + // disable aa for speed
|
| + virtual void onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle) SK_OVERRIDE {
|
| + this->INHERITED::onClipRect(rect, op, kHard_ClipEdgeStyle);
|
| + }
|
| +
|
| + // for speed, just respect the bounds, and disable AA. May give us a few
|
| + // false positives and negatives.
|
| + virtual void onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle) SK_OVERRIDE {
|
| + this->updateClipConservativelyUsingBounds(path.getBounds(), op,
|
| + path.isInverseFillType());
|
| + }
|
| + virtual void onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle) SK_OVERRIDE {
|
| + this->updateClipConservativelyUsingBounds(rrect.getBounds(), op, false);
|
| + }
|
| +
|
| +private:
|
| + SkPicture* fPicture;
|
| +
|
| + typedef SkCanvas INHERITED;
|
| +};
|
| +
|
| +// GatherGPUInfo is only intended to be called within the context of SkGpuDevice's
|
| +// EXPERIMENTAL_optimize method.
|
| +void GatherGPUInfo(SkPicture* pict, GPUAccelData* accelData) {
|
| + if (0 == pict->width() || 0 == pict->height()) {
|
| + return ;
|
| + }
|
| +
|
| + GrGatherDevice device(pict->width(), pict->height(), pict, accelData);
|
| + GrGatherCanvas canvas(&device, pict);
|
| +
|
| + canvas.gather();
|
| +}
|
| +
|
|
|
| Property changes on: src\gpu\GrPictureUtils.cpp
|
| ___________________________________________________________________
|
| Added: svn:eol-style
|
| + LF
|
|
|
|
|