Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: src/core/SkCanvas.cpp

Issue 1763143002: WIP RasterCanvasLayerAllocator (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Add allocator-constancy sanitycheck Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright 2008 The Android Open Source Project 2 * Copyright 2008 The Android Open Source Project
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkBitmapDevice.h" 8 #include "SkBitmapDevice.h"
9 #include "SkCanvas.h" 9 #include "SkCanvas.h"
10 #include "SkCanvasPriv.h" 10 #include "SkCanvasPriv.h"
11 #include "SkClipStack.h" 11 #include "SkClipStack.h"
12 #include "SkColorFilter.h" 12 #include "SkColorFilter.h"
13 #include "SkDevice.h" 13 #include "SkDevice.h"
14 #include "SkDraw.h" 14 #include "SkDraw.h"
15 #include "SkDrawable.h" 15 #include "SkDrawable.h"
16 #include "SkDrawFilter.h" 16 #include "SkDrawFilter.h"
17 #include "SkDrawLooper.h" 17 #include "SkDrawLooper.h"
18 #include "SkErrorInternals.h" 18 #include "SkErrorInternals.h"
19 #include "SkImage.h" 19 #include "SkImage.h"
20 #include "SkImage_Base.h" 20 #include "SkImage_Base.h"
21 #include "SkMatrixUtils.h" 21 #include "SkMatrixUtils.h"
22 #include "SkMetaData.h" 22 #include "SkMetaData.h"
23 #include "SkNinePatchIter.h" 23 #include "SkNinePatchIter.h"
24 #include "SkPaintPriv.h" 24 #include "SkPaintPriv.h"
25 #include "SkPatchUtils.h" 25 #include "SkPatchUtils.h"
26 #include "SkPicture.h" 26 #include "SkPicture.h"
27 #include "SkRasterCanvasLayerAllocator.h"
27 #include "SkRasterClip.h" 28 #include "SkRasterClip.h"
28 #include "SkReadPixelsRec.h" 29 #include "SkReadPixelsRec.h"
29 #include "SkRRect.h" 30 #include "SkRRect.h"
30 #include "SkSmallAllocator.h" 31 #include "SkSmallAllocator.h"
31 #include "SkSpecialImage.h" 32 #include "SkSpecialImage.h"
32 #include "SkSurface_Base.h" 33 #include "SkSurface_Base.h"
33 #include "SkTextBlob.h" 34 #include "SkTextBlob.h"
34 #include "SkTextFormatParams.h" 35 #include "SkTextFormatParams.h"
35 #include "SkTLazy.h" 36 #include "SkTLazy.h"
36 #include "SkTraceEvent.h" 37 #include "SkTraceEvent.h"
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 these are used (assuming we're not on a layer) we rebuild these cache 189 these are used (assuming we're not on a layer) we rebuild these cache
189 values: they reflect the top of the save stack, but translated and clipped 190 values: they reflect the top of the save stack, but translated and clipped
190 by the device's XY offset and bitmap-bounds. 191 by the device's XY offset and bitmap-bounds.
191 */ 192 */
192 struct DeviceCM { 193 struct DeviceCM {
193 DeviceCM* fNext; 194 DeviceCM* fNext;
194 SkBaseDevice* fDevice; 195 SkBaseDevice* fDevice;
195 SkRasterClip fClip; 196 SkRasterClip fClip;
196 SkPaint* fPaint; // may be null (in the future) 197 SkPaint* fPaint; // may be null (in the future)
197 const SkMatrix* fMatrix; 198 const SkMatrix* fMatrix;
199 SkRasterCanvasLayerAllocator* fAllocator;
200 void* fNativeContext;
198 SkMatrix fMatrixStorage; 201 SkMatrix fMatrixStorage;
199 const bool fDeviceIsBitmapDevice; 202 const bool fDeviceIsBitmapDevice;
200 203
201 DeviceCM(SkBaseDevice* device, const SkPaint* paint, SkCanvas* canvas, 204 DeviceCM(SkBaseDevice* device, const SkPaint* paint, SkCanvas* canvas,
202 bool conservativeRasterClip, bool deviceIsBitmapDevice) 205 bool conservativeRasterClip, bool deviceIsBitmapDevice)
203 : fNext(nullptr) 206 : fNext(nullptr)
204 , fClip(conservativeRasterClip) 207 , fClip(conservativeRasterClip)
208 , fAllocator(nullptr)
209 , fNativeContext(nullptr)
205 , fDeviceIsBitmapDevice(deviceIsBitmapDevice) 210 , fDeviceIsBitmapDevice(deviceIsBitmapDevice)
206 { 211 {
207 if (nullptr != device) { 212 if (nullptr != device) {
208 device->ref(); 213 device->ref();
209 device->onAttachToCanvas(canvas); 214 device->onAttachToCanvas(canvas);
210 } 215 }
211 fDevice = device; 216 fDevice = device;
212 fPaint = paint ? new SkPaint(*paint) : nullptr; 217 fPaint = paint ? new SkPaint(*paint) : nullptr;
213 } 218 }
214 219
215 ~DeviceCM() { 220 ~DeviceCM() {
216 if (fDevice) { 221 if (fDevice) {
222 if (fAllocator) {
223 fAllocator->free(fDevice->accessBitmap(false).getPixels(),
reed1 2016/05/11 18:58:24 Do we need to pass the actual pixel addr to the fr
tomhudson 2016/05/26 16:36:17 I'd assumed that allocators would have to map from
224 fNativeContext);
225 }
217 fDevice->onDetachFromCanvas(); 226 fDevice->onDetachFromCanvas();
218 fDevice->unref(); 227 fDevice->unref();
219 } 228 }
220 delete fPaint; 229 delete fPaint;
221 } 230 }
222 231
223 void reset(const SkIRect& bounds) { 232 void reset(const SkIRect& bounds) {
224 SkASSERT(!fPaint); 233 SkASSERT(!fPaint);
225 SkASSERT(!fNext); 234 SkASSERT(!fNext);
226 SkASSERT(fDevice); 235 SkASSERT(fDevice);
(...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after
662 fMCRec = (MCRec*)fMCStack.push_back(); 671 fMCRec = (MCRec*)fMCStack.push_back();
663 new (fMCRec) MCRec(fConservativeRasterClip); 672 new (fMCRec) MCRec(fConservativeRasterClip);
664 673
665 SkASSERT(sizeof(DeviceCM) <= sizeof(fDeviceCMStorage)); 674 SkASSERT(sizeof(DeviceCM) <= sizeof(fDeviceCMStorage));
666 fMCRec->fLayer = (DeviceCM*)fDeviceCMStorage; 675 fMCRec->fLayer = (DeviceCM*)fDeviceCMStorage;
667 new (fDeviceCMStorage) DeviceCM(nullptr, nullptr, nullptr, fConservativeRast erClip, false); 676 new (fDeviceCMStorage) DeviceCM(nullptr, nullptr, nullptr, fConservativeRast erClip, false);
668 677
669 fMCRec->fTopLayer = fMCRec->fLayer; 678 fMCRec->fTopLayer = fMCRec->fLayer;
670 679
671 fSurfaceBase = nullptr; 680 fSurfaceBase = nullptr;
681 fAllocator = nullptr;
672 682
673 if (device) { 683 if (device) {
674 // The root device and the canvas should always have the same pixel geom etry 684 // The root device and the canvas should always have the same pixel geom etry
675 SkASSERT(fProps.pixelGeometry() == device->surfaceProps().pixelGeometry( )); 685 SkASSERT(fProps.pixelGeometry() == device->surfaceProps().pixelGeometry( ));
676 device->onAttachToCanvas(this); 686 device->onAttachToCanvas(this);
677 fMCRec->fLayer->fDevice = SkRef(device); 687 fMCRec->fLayer->fDevice = SkRef(device);
678 fMCRec->fRasterClip.setRect(device->getGlobalBounds()); 688 fMCRec->fRasterClip.setRect(device->getGlobalBounds());
679 } 689 }
680 return device; 690 return device;
681 } 691 }
(...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after
1230 SkImageInfo info = make_layer_info(device->imageInfo(), ir.width(), ir.heigh t(), isOpaque, 1240 SkImageInfo info = make_layer_info(device->imageInfo(), ir.width(), ir.heigh t(), isOpaque,
1231 paint); 1241 paint);
1232 1242
1233 bool forceSpriteOnRestore = false; 1243 bool forceSpriteOnRestore = false;
1234 { 1244 {
1235 const bool preserveLCDText = kOpaque_SkAlphaType == info.alphaType() || 1245 const bool preserveLCDText = kOpaque_SkAlphaType == info.alphaType() ||
1236 (saveLayerFlags & kPreserveLCDText_SaveLaye rFlag); 1246 (saveLayerFlags & kPreserveLCDText_SaveLaye rFlag);
1237 const SkBaseDevice::TileUsage usage = SkBaseDevice::kNever_TileUsage; 1247 const SkBaseDevice::TileUsage usage = SkBaseDevice::kNever_TileUsage;
1238 const SkBaseDevice::CreateInfo createInfo = SkBaseDevice::CreateInfo(inf o, usage, geo, 1248 const SkBaseDevice::CreateInfo createInfo = SkBaseDevice::CreateInfo(inf o, usage, geo,
1239 pres erveLCDText, false); 1249 pres erveLCDText, false);
1240 SkBaseDevice* newDev = device->onCreateDevice(createInfo, paint); 1250 SkBaseDevice* newDev = device->onCreateDevice(createInfo, paint, fAlloca tor);
1241 if (nullptr == newDev) { 1251 if (nullptr == newDev) {
1242 // If onCreateDevice didn't succeed, try raster (e.g. PDF couldn't h andle the paint) 1252 // If onCreateDevice didn't succeed, try raster (e.g. PDF couldn't h andle the paint)
1243 const SkSurfaceProps surfaceProps(fProps.flags(), createInfo.fPixelG eometry); 1253 const SkSurfaceProps surfaceProps(fProps.flags(), createInfo.fPixelG eometry);
1244 newDev = SkBitmapDevice::Create(createInfo.fInfo, surfaceProps); 1254 newDev = SkBitmapDevice::Create(createInfo.fInfo, surfaceProps);
1245 if (nullptr == newDev) { 1255 if (nullptr == newDev) {
1246 SkErrorInternals::SetError(kInternalError_SkError, 1256 SkErrorInternals::SetError(kInternalError_SkError,
1247 "Unable to create device for layer.") ; 1257 "Unable to create device for layer.") ;
1248 return; 1258 return;
1249 } 1259 }
1250 forceSpriteOnRestore = true; 1260 forceSpriteOnRestore = true;
1251 } 1261 }
1252 device = newDev; 1262 device = newDev;
1253 } 1263 }
1254 device->setOrigin(ir.fLeft, ir.fTop); 1264 device->setOrigin(ir.fLeft, ir.fTop);
1255 1265
1256 if (rec.fBackdrop) { 1266 if (rec.fBackdrop) {
1257 draw_filter_into_device(fMCRec->fTopLayer->fDevice, rec.fBackdrop, devic e, fMCRec->fMatrix); 1267 draw_filter_into_device(fMCRec->fTopLayer->fDevice, rec.fBackdrop, devic e, fMCRec->fMatrix);
1258 } 1268 }
1259 1269
1260 DeviceCM* layer = 1270 DeviceCM* layer =
1261 new DeviceCM(device, paint, this, fConservativeRasterClip, forceSpri teOnRestore); 1271 new DeviceCM(device, paint, this, fConservativeRasterClip, forceSpri teOnRestore);
1262 device->unref(); 1272 device->unref();
1263 1273
1264 layer->fNext = fMCRec->fTopLayer; 1274 layer->fNext = fMCRec->fTopLayer;
1275 layer->fAllocator = fAllocator;
1276 layer->fNativeContext = fAllocator
1277 ? fAllocator->getNativeContext(device->accessBitmap(false).getPixels())
1278 : nullptr;
1265 fMCRec->fLayer = layer; 1279 fMCRec->fLayer = layer;
1266 fMCRec->fTopLayer = layer; // this field is NOT an owner of layer 1280 fMCRec->fTopLayer = layer; // this field is NOT an owner of layer
1267 } 1281 }
1268 1282
1269 int SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha) { 1283 int SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha) {
1270 if (0xFF == alpha) { 1284 if (0xFF == alpha) {
1271 return this->saveLayer(bounds, nullptr); 1285 return this->saveLayer(bounds, nullptr);
1272 } else { 1286 } else {
1273 SkPaint tmpPaint; 1287 SkPaint tmpPaint;
1274 tmpPaint.setAlpha(alpha); 1288 tmpPaint.setAlpha(alpha);
1275 return this->saveLayer(bounds, &tmpPaint); 1289 return this->saveLayer(bounds, &tmpPaint);
1276 } 1290 }
1277 } 1291 }
1278 1292
1279 void SkCanvas::internalRestore() { 1293 void SkCanvas::internalRestore() {
1280 SkASSERT(fMCStack.count() != 0); 1294 SkASSERT(fMCStack.count() != 0);
1281 1295
1282 fDeviceCMDirty = true; 1296 fDeviceCMDirty = true;
1283 fCachedLocalClipBoundsDirty = true; 1297 fCachedLocalClipBoundsDirty = true;
1284 1298
1285 fClipStack->restore(); 1299 fClipStack->restore();
1286 1300
1287 // reserve our layer (if any) 1301 // reserve our layer (if any)
1288 DeviceCM* layer = fMCRec->fLayer; // may be null 1302 DeviceCM* layer = fMCRec->fLayer; // may be null
1303
1289 // now detach it from fMCRec so we can pop(). Gets freed after its drawn 1304 // now detach it from fMCRec so we can pop(). Gets freed after its drawn
1290 fMCRec->fLayer = nullptr; 1305 fMCRec->fLayer = nullptr;
1291 1306
1292 // now do the normal restore() 1307 // now do the normal restore()
1293 fMCRec->~MCRec(); // balanced in save() 1308 fMCRec->~MCRec(); // balanced in save()
1294 fMCStack.pop_back(); 1309 fMCStack.pop_back();
1295 fMCRec = (MCRec*)fMCStack.back(); 1310 fMCRec = (MCRec*)fMCStack.back();
1296 1311
1297 /* Time to draw the layer's offscreen. We can't call the public drawSprite, 1312 /* Time to draw the layer's offscreen. We can't call the public drawSprite,
1298 since if we're being recorded, we don't want to record this (the 1313 since if we're being recorded, we don't want to record this (the
1299 recorder will have already recorded the restore). 1314 recorder will have already recorded the restore).
1300 */ 1315 */
1301 if (layer) { 1316 if (layer) {
1317 SkASSERT(layer->fAllocator == fAllocator);
1302 if (layer->fNext) { 1318 if (layer->fNext) {
1303 const SkIPoint& origin = layer->fDevice->getOrigin(); 1319 const SkIPoint& origin = layer->fDevice->getOrigin();
1304 this->internalDrawDevice(layer->fDevice, origin.x(), origin.y(), 1320 this->internalDrawDevice(layer->fDevice, origin.x(), origin.y(),
1305 layer->fPaint, layer->fDeviceIsBitmapDevice ); 1321 layer->fPaint, layer->fDeviceIsBitmapDevice );
1306 // reset this, since internalDrawDevice will have set it to true 1322 // reset this, since internalDrawDevice will have set it to true
1307 fDeviceCMDirty = true; 1323 fDeviceCMDirty = true;
1308 delete layer; 1324 delete layer;
1309 } else { 1325 } else {
1310 // we're at the root 1326 // we're at the root
1311 SkASSERT(layer == (void*)fDeviceCMStorage); 1327 SkASSERT(layer == (void*)fDeviceCMStorage);
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after
1730 1746
1731 void SkCanvas::replayClips(ClipVisitor* visitor) const { 1747 void SkCanvas::replayClips(ClipVisitor* visitor) const {
1732 SkClipStack::B2TIter iter(*fClipStack); 1748 SkClipStack::B2TIter iter(*fClipStack);
1733 const SkClipStack::Element* element; 1749 const SkClipStack::Element* element;
1734 1750
1735 while ((element = iter.next()) != nullptr) { 1751 while ((element = iter.next()) != nullptr) {
1736 element->replay(visitor); 1752 element->replay(visitor);
1737 } 1753 }
1738 } 1754 }
1739 1755
1756 void* SkCanvas::getTopLayerNative() const {
1757 return fMCRec->fLayer->fNativeContext;
1758 }
1759
1760
1740 /////////////////////////////////////////////////////////////////////////////// 1761 ///////////////////////////////////////////////////////////////////////////////
1741 1762
1742 bool SkCanvas::isClipEmpty() const { 1763 bool SkCanvas::isClipEmpty() const {
1743 return fMCRec->fRasterClip.isEmpty(); 1764 return fMCRec->fRasterClip.isEmpty();
1744 } 1765 }
1745 1766
1746 bool SkCanvas::isClipRect() const { 1767 bool SkCanvas::isClipRect() const {
1747 return fMCRec->fRasterClip.isRect(); 1768 return fMCRec->fRasterClip.isRect();
1748 } 1769 }
1749 1770
(...skipping 1286 matching lines...) Expand 10 before | Expand all | Expand 10 after
3036 } 3057 }
3037 3058
3038 if (matrix) { 3059 if (matrix) {
3039 canvas->concat(*matrix); 3060 canvas->concat(*matrix);
3040 } 3061 }
3041 } 3062 }
3042 3063
3043 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { 3064 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() {
3044 fCanvas->restoreToCount(fSaveCount); 3065 fCanvas->restoreToCount(fSaveCount);
3045 } 3066 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698