6fed2f6d9ffa135cdb1dd6c1454c6580c9411065
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / gpu / GrPictureUtils.cpp
1 /*
2  * Copyright 2014 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7
8 #include "GrPictureUtils.h"
9 #include "SkDevice.h"
10 #include "SkDraw.h"
11 #include "SkPaintPriv.h"
12 #include "SkPicturePlayback.h"
13
14 SkPicture::AccelData::Key GPUAccelData::ComputeAccelDataKey() {
15     static const SkPicture::AccelData::Key gGPUID = SkPicture::AccelData::GenerateDomain();
16
17     return gGPUID;
18 }
19
20 // The GrGather device performs GPU-backend-specific preprocessing on
21 // a picture. The results are stored in a GPUAccelData.
22 //
23 // Currently the only interesting work is done in drawDevice (i.e., when a
24 // saveLayer is collapsed back into its parent) and, maybe, in onCreateDevice.
25 // All the current work could be done much more efficiently by just traversing the
26 // raw op codes in the SkPicture (although we would still need to replay all the
27 // clip calls).
28 class GrGatherDevice : public SkBaseDevice {
29 public:
30     SK_DECLARE_INST_COUNT(GrGatherDevice)
31
32     GrGatherDevice(int width, int height, const SkPicture* picture, GPUAccelData* accelData,
33                    int saveLayerDepth) {
34         fPicture = picture;
35         fSaveLayerDepth = saveLayerDepth;
36         fInfo.fValid = true;
37         fInfo.fSize.set(width, height);
38         fInfo.fPaint = NULL;
39         fInfo.fSaveLayerOpID = fPicture->EXPERIMENTAL_curOpID();
40         fInfo.fRestoreOpID = 0;
41         fInfo.fHasNestedLayers = false;
42         fInfo.fIsNested = (2 == fSaveLayerDepth);
43
44         fEmptyBitmap.setInfo(SkImageInfo::MakeUnknown(fInfo.fSize.fWidth, fInfo.fSize.fHeight));
45         fAccelData = accelData;
46         fAlreadyDrawn = false;
47     }
48
49     virtual ~GrGatherDevice() { }
50
51     virtual SkImageInfo imageInfo() const SK_OVERRIDE {
52         return fEmptyBitmap.info();
53     }
54
55 #ifdef SK_SUPPORT_LEGACY_WRITEPIXELSCONFIG
56     virtual void writePixels(const SkBitmap& bitmap, int x, int y,
57                              SkCanvas::Config8888 config8888) SK_OVERRIDE {
58         NotSupported();
59     }
60 #endif
61     virtual GrRenderTarget* accessRenderTarget() SK_OVERRIDE { return NULL; }
62
63 protected:
64     virtual bool filterTextFlags(const SkPaint& paint, TextFlags*) SK_OVERRIDE {
65         return false;
66     }
67     virtual void clear(SkColor color) SK_OVERRIDE {
68         NothingToDo();
69     }
70     virtual void drawPaint(const SkDraw& draw, const SkPaint& paint) SK_OVERRIDE {
71     }
72     virtual void drawPoints(const SkDraw& draw, SkCanvas::PointMode mode, size_t count,
73                             const SkPoint points[], const SkPaint& paint) SK_OVERRIDE {
74     }
75     virtual void drawRect(const SkDraw& draw, const SkRect& rect,
76                           const SkPaint& paint) SK_OVERRIDE {
77     }
78     virtual void drawOval(const SkDraw& draw, const SkRect& rect,
79                           const SkPaint& paint) SK_OVERRIDE {
80     }
81     virtual void drawRRect(const SkDraw& draw, const SkRRect& rrect,
82                            const SkPaint& paint) SK_OVERRIDE {
83     }
84     virtual void drawPath(const SkDraw& draw, const SkPath& path,
85                           const SkPaint& paint, const SkMatrix* prePathMatrix,
86                           bool pathIsMutable) SK_OVERRIDE {
87     }
88     virtual void drawBitmap(const SkDraw& draw, const SkBitmap& bitmap,
89                             const SkMatrix& matrix, const SkPaint& paint) SK_OVERRIDE {
90     }
91     virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap,
92                             int x, int y, const SkPaint& paint) SK_OVERRIDE {
93     }
94     virtual void drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap,
95                                 const SkRect* srcOrNull, const SkRect& dst,
96                                 const SkPaint& paint,
97                                 SkCanvas::DrawBitmapRectFlags flags) SK_OVERRIDE {
98     }
99     virtual void drawText(const SkDraw& draw, const void* text, size_t len,
100                           SkScalar x, SkScalar y,
101                           const SkPaint& paint) SK_OVERRIDE {
102     }
103     virtual void drawPosText(const SkDraw& draw, const void* text, size_t len,
104                              const SkScalar pos[], SkScalar constY,
105                              int scalarsPerPos, const SkPaint& paint) SK_OVERRIDE {
106     }
107     virtual void drawTextOnPath(const SkDraw& draw, const void* text, size_t len,
108                                 const SkPath& path, const SkMatrix* matrix,
109                                 const SkPaint& paint) SK_OVERRIDE {
110     }
111     virtual void drawVertices(const SkDraw& draw, SkCanvas::VertexMode, int vertexCount,
112                               const SkPoint verts[], const SkPoint texs[],
113                               const SkColor colors[], SkXfermode* xmode,
114                               const uint16_t indices[], int indexCount,
115                               const SkPaint& paint) SK_OVERRIDE {
116     }
117     virtual void drawDevice(const SkDraw& draw, SkBaseDevice* deviceIn, int x, int y,
118                             const SkPaint& paint) SK_OVERRIDE {
119         // deviceIn is the one that is being "restored" back to its parent
120         GrGatherDevice* device = static_cast<GrGatherDevice*>(deviceIn);
121
122         if (device->fAlreadyDrawn) {
123             return;
124         }
125
126         device->fInfo.fRestoreOpID = fPicture->EXPERIMENTAL_curOpID();
127         device->fInfo.fCTM = *draw.fMatrix;
128         device->fInfo.fCTM.postTranslate(SkIntToScalar(-device->getOrigin().fX),
129                                          SkIntToScalar(-device->getOrigin().fY));
130
131         device->fInfo.fOffset = device->getOrigin();
132
133         if (NeedsDeepCopy(paint)) {
134             // This NULL acts as a signal that the paint was uncopyable (for now)
135             device->fInfo.fPaint = NULL;
136             device->fInfo.fValid = false;
137         } else {
138             device->fInfo.fPaint = SkNEW_ARGS(SkPaint, (paint));
139         }
140
141         fAccelData->addSaveLayerInfo(device->fInfo);
142         device->fAlreadyDrawn = true;
143     }
144     // TODO: allow this call to return failure, or move to SkBitmapDevice only.
145     virtual const SkBitmap& onAccessBitmap() SK_OVERRIDE {
146         return fEmptyBitmap;
147     }
148 #ifdef SK_SUPPORT_LEGACY_READPIXELSCONFIG
149     virtual bool onReadPixels(const SkBitmap& bitmap,
150                               int x, int y,
151                               SkCanvas::Config8888 config8888) SK_OVERRIDE {
152         NotSupported();
153         return false;
154     }
155 #endif
156     virtual void lockPixels() SK_OVERRIDE { NothingToDo(); }
157     virtual void unlockPixels() SK_OVERRIDE { NothingToDo(); }
158     virtual bool allowImageFilter(const SkImageFilter*) SK_OVERRIDE { return false; }
159     virtual bool canHandleImageFilter(const SkImageFilter*) SK_OVERRIDE { return false; }
160     virtual bool filterImage(const SkImageFilter*, const SkBitmap&, const SkImageFilter::Context&,
161                              SkBitmap* result, SkIPoint* offset) SK_OVERRIDE {
162         return false;
163     }
164
165 private:
166     // The picture being processed
167     const SkPicture *fPicture;
168
169     SkBitmap fEmptyBitmap; // legacy -- need to remove
170
171     // All information gathered during the gather process is stored here
172     GPUAccelData* fAccelData;
173
174     // true if this device has already been drawn back to its parent(s) at least
175     // once.
176     bool   fAlreadyDrawn;
177
178     // The information regarding the saveLayer call this device represents.
179     GPUAccelData::SaveLayerInfo fInfo;
180
181     // The depth of this device in the saveLayer stack
182     int fSaveLayerDepth;
183
184     virtual void replaceBitmapBackendForRasterSurface(const SkBitmap&) SK_OVERRIDE {
185         NotSupported();
186     }
187
188     virtual SkBaseDevice* onCreateDevice(const SkImageInfo& info, Usage usage) SK_OVERRIDE {
189         // we expect to only get called via savelayer, in which case it is fine.
190         SkASSERT(kSaveLayer_Usage == usage);
191
192         fInfo.fHasNestedLayers = true;
193         return SkNEW_ARGS(GrGatherDevice, (info.width(), info.height(), fPicture,
194                                            fAccelData, fSaveLayerDepth+1));
195     }
196
197     virtual void flush() SK_OVERRIDE {}
198
199     static void NotSupported() {
200         SkDEBUGFAIL("this method should never be called");
201     }
202
203     static void NothingToDo() {}
204
205     typedef SkBaseDevice INHERITED;
206 };
207
208 // The GrGatherCanvas allows saveLayers but simplifies clipping. It is really
209 // only intended to be used as:
210 //
211 //      GrGatherDevice dev(w, h, picture, accelData);
212 //      GrGatherCanvas canvas(..., picture);
213 //      canvas.gather();
214 //
215 // which is all just to fill in 'accelData'
216 class SK_API GrGatherCanvas : public SkCanvas {
217 public:
218     GrGatherCanvas(GrGatherDevice* device, const SkPicture* pict)
219         : INHERITED(device)
220         , fPicture(pict) {
221     }
222
223     void gather() {
224         if (NULL == fPicture || 0 == fPicture->width() || 0 == fPicture->height()) {
225             return;
226         }
227
228         this->clipRect(SkRect::MakeWH(SkIntToScalar(fPicture->width()),
229                                       SkIntToScalar(fPicture->height())),
230                        SkRegion::kIntersect_Op, false);
231         this->drawPicture(fPicture);
232     }
233
234 protected:
235     // disable aa for speed
236     virtual void onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle) SK_OVERRIDE {
237         this->INHERITED::onClipRect(rect, op, kHard_ClipEdgeStyle);
238     }
239
240     // for speed, just respect the bounds, and disable AA. May give us a few
241     // false positives and negatives.
242     virtual void onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle) SK_OVERRIDE {
243         this->updateClipConservativelyUsingBounds(path.getBounds(), op,
244                                                   path.isInverseFillType());
245     }
246     virtual void onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle) SK_OVERRIDE {
247         this->updateClipConservativelyUsingBounds(rrect.getBounds(), op, false);
248     }
249
250     virtual void onDrawPicture(const SkPicture* picture) SK_OVERRIDE {
251         // BBH-based rendering doesn't re-issue many of the operations the gather
252         // process cares about (e.g., saves and restores) so it must be disabled.
253         if (NULL != picture->fPlayback) {
254             picture->fPlayback->setUseBBH(false);
255         }
256         picture->draw(this);
257         if (NULL != picture->fPlayback) {
258             picture->fPlayback->setUseBBH(true);
259         }
260     }
261
262 private:
263     const SkPicture* fPicture;
264
265     typedef SkCanvas INHERITED;
266 };
267
268 // GatherGPUInfo is only intended to be called within the context of SkGpuDevice's
269 // EXPERIMENTAL_optimize method.
270 void GatherGPUInfo(const SkPicture* pict, GPUAccelData* accelData) {
271     if (0 == pict->width() || 0 == pict->height()) {
272         return ;
273     }
274
275     GrGatherDevice device(pict->width(), pict->height(), pict, accelData, 0);
276     GrGatherCanvas canvas(&device, pict);
277
278     canvas.gather();
279 }