blob: 61a7ab61c7e30439c0e79d7855059785c5a715b8 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001/*
2 * Copyright 2011 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 */
robertphillips@google.com53238bc2013-08-30 13:12:10 +00007
reed@android.com8a1c16f2008-12-17 15:59:43 +00008#include "SkDevice.h"
reed@google.coma7d94852011-03-30 21:23:07 +00009#include "SkMetaData.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +000010
robertphillips@google.com53238bc2013-08-30 13:12:10 +000011#if SK_PMCOLOR_BYTE_ORDER(B,G,R,A)
12 const SkCanvas::Config8888 SkBaseDevice::kPMColorAlias = SkCanvas::kBGRA_Premul_Config8888;
13#elif SK_PMCOLOR_BYTE_ORDER(R,G,B,A)
14 const SkCanvas::Config8888 SkBaseDevice::kPMColorAlias = SkCanvas::kRGBA_Premul_Config8888;
15#else
16 const SkCanvas::Config8888 SkBaseDevice::kPMColorAlias = (SkCanvas::Config8888) -1;
17#endif
robertphillips@google.com15e9d3e2012-06-21 20:25:03 +000018
mike@reedtribe.orgea4ac972011-04-26 11:48:33 +000019///////////////////////////////////////////////////////////////////////////////
reed@google.com76f10a32014-02-05 15:32:21 +000020
robertphillips@google.com1f2f3382013-08-29 11:54:56 +000021SkBaseDevice::SkBaseDevice()
skia.committer@gmail.com772c4e62013-08-30 07:01:34 +000022 : fLeakyProperties(SkDeviceProperties::MakeDefault())
robertphillips@google.com40a1ae42012-07-13 15:36:15 +000023#ifdef SK_DEBUG
rmistry@google.comfbfcd562012-08-23 18:09:54 +000024 , fAttachedToCanvas(false)
robertphillips@google.com40a1ae42012-07-13 15:36:15 +000025#endif
26{
reed@google.com6f8f2922011-03-04 22:27:10 +000027 fOrigin.setZero();
reed@google.comaf951c92011-06-16 19:10:39 +000028 fMetaData = NULL;
reed@android.comf2b98d62010-12-20 18:26:13 +000029}
reed@android.com8a1c16f2008-12-17 15:59:43 +000030
robertphillips@google.com1f2f3382013-08-29 11:54:56 +000031SkBaseDevice::SkBaseDevice(const SkDeviceProperties& deviceProperties)
bungeman@google.com532470f2013-01-22 19:25:14 +000032 : fLeakyProperties(deviceProperties)
33#ifdef SK_DEBUG
34 , fAttachedToCanvas(false)
robertphillips@google.com40a1ae42012-07-13 15:36:15 +000035#endif
36{
reed@google.comaf951c92011-06-16 19:10:39 +000037 fOrigin.setZero();
38 fMetaData = NULL;
robertphillips@google.com1f2f3382013-08-29 11:54:56 +000039}
40
robertphillips@google.com1f2f3382013-08-29 11:54:56 +000041SkBaseDevice::~SkBaseDevice() {
reed@google.coma7d94852011-03-30 21:23:07 +000042 delete fMetaData;
43}
44
commit-bot@chromium.org15a14052014-02-16 00:59:25 +000045SkBaseDevice* SkBaseDevice::createCompatibleDevice(const SkImageInfo& info) {
46#ifdef SK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG
47 // We call the old method to support older subclasses.
48 // If they have, we return their device, else we use the new impl.
49 SkBitmap::Config config = SkColorTypeToBitmapConfig(info.colorType());
50 SkBaseDevice* dev = this->onCreateCompatibleDevice(config,
51 info.width(),
52 info.height(),
53 info.isOpaque(),
54 kGeneral_Usage);
55 if (dev) {
56 return dev;
57 }
58 // fall through to new impl
59#endif
60 return this->onCreateDevice(info, kGeneral_Usage);
61}
62
63SkBaseDevice* SkBaseDevice::createCompatibleDeviceForSaveLayer(const SkImageInfo& info) {
64#ifdef SK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG
65 // We call the old method to support older subclasses.
66 // If they have, we return their device, else we use the new impl.
67 SkBitmap::Config config = SkColorTypeToBitmapConfig(info.colorType());
68 SkBaseDevice* dev = this->onCreateCompatibleDevice(config,
69 info.width(),
70 info.height(),
71 info.isOpaque(),
72 kSaveLayer_Usage);
73 if (dev) {
74 return dev;
75 }
76 // fall through to new impl
77#endif
78 return this->onCreateDevice(info, kSaveLayer_Usage);
79}
80
81#ifdef SK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG
robertphillips@google.com1f2f3382013-08-29 11:54:56 +000082SkBaseDevice* SkBaseDevice::createCompatibleDevice(SkBitmap::Config config,
83 int width, int height,
84 bool isOpaque) {
commit-bot@chromium.org15a14052014-02-16 00:59:25 +000085 SkImageInfo info = SkImageInfo::Make(width, height,
86 SkBitmapConfigToColorType(config),
87 isOpaque ? kOpaque_SkAlphaType
88 : kPremul_SkAlphaType);
89 return this->createCompatibleDevice(info);
bsalomon@google.come97f0852011-06-17 13:10:25 +000090}
commit-bot@chromium.org15a14052014-02-16 00:59:25 +000091#endif
bsalomon@google.come97f0852011-06-17 13:10:25 +000092
robertphillips@google.com1f2f3382013-08-29 11:54:56 +000093SkMetaData& SkBaseDevice::getMetaData() {
reed@google.coma7d94852011-03-30 21:23:07 +000094 // metadata users are rare, so we lazily allocate it. If that changes we
95 // can decide to just make it a field in the device (rather than a ptr)
96 if (NULL == fMetaData) {
97 fMetaData = new SkMetaData;
98 }
99 return *fMetaData;
100}
101
commit-bot@chromium.orgc3bd8af2014-02-13 17:14:46 +0000102// TODO: should make this guy pure-virtual.
103SkImageInfo SkBaseDevice::imageInfo() const {
reed@google.com900ecf22014-02-20 20:55:37 +0000104 return SkImageInfo::MakeUnknown(this->width(), this->height());
commit-bot@chromium.orgc3bd8af2014-02-13 17:14:46 +0000105}
106
robertphillips@google.com1f2f3382013-08-29 11:54:56 +0000107const SkBitmap& SkBaseDevice::accessBitmap(bool changePixels) {
108 const SkBitmap& bitmap = this->onAccessBitmap();
reed@android.com8a1c16f2008-12-17 15:59:43 +0000109 if (changePixels) {
junov@chromium.org1f9767c2012-02-07 16:27:57 +0000110 bitmap.notifyPixelsChanged();
reed@android.com8a1c16f2008-12-17 15:59:43 +0000111 }
junov@chromium.org1f9767c2012-02-07 16:27:57 +0000112 return bitmap;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000113}
114
commit-bot@chromium.orga713f9c2014-03-17 21:31:26 +0000115#ifdef SK_SUPPORT_LEGACY_READPIXELSCONFIG
robertphillips@google.com1f2f3382013-08-29 11:54:56 +0000116bool SkBaseDevice::readPixels(SkBitmap* bitmap, int x, int y,
117 SkCanvas::Config8888 config8888) {
bsalomon@google.comc6980972011-11-02 19:57:21 +0000118 if (SkBitmap::kARGB_8888_Config != bitmap->config() ||
119 NULL != bitmap->getTexture()) {
reed@android.comf2b98d62010-12-20 18:26:13 +0000120 return false;
121 }
122
bsalomon@google.comc6980972011-11-02 19:57:21 +0000123 const SkBitmap& src = this->accessBitmap(false);
124
125 SkIRect srcRect = SkIRect::MakeXYWH(x, y, bitmap->width(),
126 bitmap->height());
127 SkIRect devbounds = SkIRect::MakeWH(src.width(), src.height());
128 if (!srcRect.intersect(devbounds)) {
reed@android.comf2b98d62010-12-20 18:26:13 +0000129 return false;
130 }
131
132 SkBitmap tmp;
bsalomon@google.comc6980972011-11-02 19:57:21 +0000133 SkBitmap* bmp;
134 if (bitmap->isNull()) {
reed@google.com9ebcac52014-01-24 18:53:42 +0000135 if (!tmp.allocPixels(SkImageInfo::MakeN32Premul(bitmap->width(),
136 bitmap->height()))) {
bsalomon@google.comc6980972011-11-02 19:57:21 +0000137 return false;
138 }
139 bmp = &tmp;
140 } else {
141 bmp = bitmap;
bsalomon@google.com1a8ddf02011-11-02 19:34:16 +0000142 }
bsalomon@google.comace7bd52011-11-02 19:39:51 +0000143
bsalomon@google.comc6980972011-11-02 19:57:21 +0000144 SkIRect subrect = srcRect;
145 subrect.offset(-x, -y);
146 SkBitmap bmpSubset;
147 bmp->extractSubset(&bmpSubset, subrect);
148
bsalomon@google.com6850eab2011-11-03 20:29:47 +0000149 bool result = this->onReadPixels(bmpSubset,
150 srcRect.fLeft,
151 srcRect.fTop,
152 config8888);
bsalomon@google.comc6980972011-11-02 19:57:21 +0000153 if (result && bmp == &tmp) {
154 tmp.swap(*bitmap);
155 }
156 return result;
157}
commit-bot@chromium.orga713f9c2014-03-17 21:31:26 +0000158bool SkBaseDevice::onReadPixels(const SkBitmap&, int x, int y, SkCanvas::Config8888) {
159 return false;
160}
161#endif
reed@google.com76f10a32014-02-05 15:32:21 +0000162
163SkSurface* SkBaseDevice::newSurface(const SkImageInfo&) { return NULL; }
commit-bot@chromium.orgc3bd8af2014-02-13 17:14:46 +0000164
165const void* SkBaseDevice::peekPixels(SkImageInfo*, size_t*) { return NULL; }
commit-bot@chromium.orged9806f2014-02-21 02:32:36 +0000166
167void SkBaseDevice::drawDRRect(const SkDraw& draw, const SkRRect& outer,
168 const SkRRect& inner, const SkPaint& paint) {
169 SkPath path;
170 path.addRRect(outer);
171 path.addRRect(inner);
172 path.setFillType(SkPath::kEvenOdd_FillType);
173
174 const SkMatrix* preMatrix = NULL;
175 const bool pathIsMutable = true;
176 this->drawPath(draw, path, paint, preMatrix, pathIsMutable);
177}
commit-bot@chromium.org4cd9e212014-03-07 03:25:16 +0000178
commit-bot@chromium.orga713f9c2014-03-17 21:31:26 +0000179bool SkBaseDevice::readPixels(const SkImageInfo& info, void* dstP, size_t rowBytes, int x, int y) {
180#ifdef SK_DEBUG
181 SkASSERT(info.width() > 0 && info.height() > 0);
182 SkASSERT(dstP);
183 SkASSERT(rowBytes >= info.minRowBytes());
184 SkASSERT(x >= 0 && y >= 0);
185
186 const SkImageInfo& srcInfo = this->imageInfo();
187 SkASSERT(x + info.width() <= srcInfo.width());
188 SkASSERT(y + info.height() <= srcInfo.height());
189#endif
190 return this->onReadPixels(info, dstP, rowBytes, x, y);
191}
192
commit-bot@chromium.org4ef54f82014-03-17 17:03:18 +0000193bool SkBaseDevice::writePixels(const SkImageInfo& info, const void* pixels, size_t rowBytes,
194 int x, int y) {
commit-bot@chromium.org4cd9e212014-03-07 03:25:16 +0000195#ifdef SK_DEBUG
196 SkASSERT(info.width() > 0 && info.height() > 0);
197 SkASSERT(pixels);
198 SkASSERT(rowBytes >= info.minRowBytes());
199 SkASSERT(x >= 0 && y >= 0);
200
201 const SkImageInfo& dstInfo = this->imageInfo();
202 SkASSERT(x + info.width() <= dstInfo.width());
203 SkASSERT(y + info.height() <= dstInfo.height());
204#endif
205 return this->onWritePixels(info, pixels, rowBytes, x, y);
206}
207
208bool SkBaseDevice::onWritePixels(const SkImageInfo&, const void*, size_t, int, int) {
209 return false;
210}
211
commit-bot@chromium.orga713f9c2014-03-17 21:31:26 +0000212bool SkBaseDevice::onReadPixels(const SkImageInfo&, void*, size_t, int x, int y) {
commit-bot@chromium.org2cccf832014-03-12 03:04:08 +0000213 return false;
214}
215
reed@google.com9c135db2014-03-12 18:28:35 +0000216void* SkBaseDevice::accessPixels(SkImageInfo* info, size_t* rowBytes) {
217 SkImageInfo tmpInfo;
218 size_t tmpRowBytes;
219 if (NULL == info) {
220 info = &tmpInfo;
221 }
222 if (NULL == rowBytes) {
223 rowBytes = &tmpRowBytes;
224 }
225 return this->onAccessPixels(info, rowBytes);
226}
227
228void* SkBaseDevice::onAccessPixels(SkImageInfo* info, size_t* rowBytes) {
229 return NULL;
230}
231
commit-bot@chromium.org145d1c02014-03-16 19:46:36 +0000232void SkBaseDevice::EXPERIMENTAL_optimize(SkPicture* picture) {
233 // The base class doesn't perform any analysis but derived classes may
234}
235
236bool SkBaseDevice::EXPERIMENTAL_drawPicture(const SkPicture& picture) {
237 // The base class doesn't perform any accelerated picture rendering
238 return false;
239}