OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 } |
OLD | NEW |