blob: 4fc904539b9acd6fb5f938eb931c56d94cc711bb [file] [log] [blame]
reed@google.comc9062042012-07-30 18:06:00 +00001/*
2 * Copyright 2012 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
reed@google.com9ea5a3b2012-07-30 21:03:46 +00008#include "SkSurface_Base.h"
reed@google.com889b09e2012-07-27 21:10:42 +00009#include "SkImagePriv.h"
10#include "SkCanvas.h"
11
reed4a8126e2014-09-22 07:29:03 -070012#include "SkFontLCDConfig.h"
13static SkPixelGeometry compute_default_geometry() {
14 SkFontLCDConfig::LCDOrder order = SkFontLCDConfig::GetSubpixelOrder();
15 if (SkFontLCDConfig::kNONE_LCDOrder == order) {
16 return kUnknown_SkPixelGeometry;
17 } else {
18 // Bit0 is RGB(0), BGR(1)
19 // Bit1 is H(0), V(1)
20 const SkPixelGeometry gGeo[] = {
21 kRGB_H_SkPixelGeometry,
22 kBGR_H_SkPixelGeometry,
23 kRGB_V_SkPixelGeometry,
24 kBGR_V_SkPixelGeometry,
25 };
26 int index = 0;
27 if (SkFontLCDConfig::kBGR_LCDOrder == order) {
28 index |= 1;
29 }
30 if (SkFontLCDConfig::kVertical_LCDOrientation == SkFontLCDConfig::GetSubpixelOrientation()){
31 index |= 2;
32 }
33 return gGeo[index];
34 }
35}
36
37SkSurfaceProps::SkSurfaceProps() : fFlags(0), fPixelGeometry(kUnknown_SkPixelGeometry) {}
38
39SkSurfaceProps::SkSurfaceProps(InitType) : fFlags(0), fPixelGeometry(compute_default_geometry()) {}
40
41SkSurfaceProps::SkSurfaceProps(uint32_t flags, InitType)
42 : fFlags(flags)
43 , fPixelGeometry(compute_default_geometry())
44{}
45
46SkSurfaceProps::SkSurfaceProps(uint32_t flags, SkPixelGeometry pg)
47 : fFlags(flags), fPixelGeometry(pg)
48{}
49
reed4af267b2014-11-21 08:46:37 -080050SkSurfaceProps::SkSurfaceProps(const SkSurfaceProps& other)
51 : fFlags(other.fFlags)
52 , fPixelGeometry(other.fPixelGeometry)
53{}
54
reed@google.com889b09e2012-07-27 21:10:42 +000055///////////////////////////////////////////////////////////////////////////////
56
reed4a8126e2014-09-22 07:29:03 -070057SkSurface_Base::SkSurface_Base(int width, int height, const SkSurfaceProps* props)
58 : INHERITED(width, height, props)
59{
halcanary96fcdcc2015-08-27 07:41:13 -070060 fCachedCanvas = nullptr;
61 fCachedImage = nullptr;
reed@google.com9ea5a3b2012-07-30 21:03:46 +000062}
reed@google.com889b09e2012-07-27 21:10:42 +000063
reed4a8126e2014-09-22 07:29:03 -070064SkSurface_Base::SkSurface_Base(const SkImageInfo& info, const SkSurfaceProps* props)
65 : INHERITED(info, props)
66{
halcanary96fcdcc2015-08-27 07:41:13 -070067 fCachedCanvas = nullptr;
68 fCachedImage = nullptr;
reed@google.com1360c522014-01-08 21:25:26 +000069}
70
reed@google.com9ea5a3b2012-07-30 21:03:46 +000071SkSurface_Base::~SkSurface_Base() {
reed@google.com97af1a62012-08-28 12:19:02 +000072 // in case the canvas outsurvives us, we null the callback
73 if (fCachedCanvas) {
halcanary96fcdcc2015-08-27 07:41:13 -070074 fCachedCanvas->setSurfaceBase(nullptr);
reed@google.com97af1a62012-08-28 12:19:02 +000075 }
76
77 SkSafeUnref(fCachedImage);
reed@google.com9ea5a3b2012-07-30 21:03:46 +000078 SkSafeUnref(fCachedCanvas);
79}
reed@google.com889b09e2012-07-27 21:10:42 +000080
reed4a8126e2014-09-22 07:29:03 -070081void SkSurface_Base::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint) {
bsalomoneaaaf0b2015-01-23 08:08:04 -080082 SkImage* image = this->newImageSnapshot(kYes_Budgeted);
reed@google.com889b09e2012-07-27 21:10:42 +000083 if (image) {
piotaixrb5fae932014-09-24 13:03:30 -070084 canvas->drawImage(image, x, y, paint);
reed@google.com889b09e2012-07-27 21:10:42 +000085 image->unref();
86 }
87}
88
reedc83a2972015-07-16 07:40:45 -070089bool SkSurface_Base::outstandingImageSnapshot() const {
90 return fCachedImage && !fCachedImage->unique();
91}
92
commit-bot@chromium.orgc4c98702013-04-22 14:28:01 +000093void SkSurface_Base::aboutToDraw(ContentChangeMode mode) {
reed@google.com97af1a62012-08-28 12:19:02 +000094 this->dirtyGenerationID();
95
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +000096 SkASSERT(!fCachedCanvas || fCachedCanvas->getSurfaceBase() == this);
reed@google.com97af1a62012-08-28 12:19:02 +000097
bsalomon49f085d2014-09-05 13:34:00 -070098 if (fCachedImage) {
reed@google.com97af1a62012-08-28 12:19:02 +000099 // the surface may need to fork its backend, if its sharing it with
100 // the cached image. Note: we only call if there is an outstanding owner
101 // on the image (besides us).
reed26e0e582015-07-29 11:44:52 -0700102 bool unique = fCachedImage->unique();
103 if (!unique) {
commit-bot@chromium.orgc4c98702013-04-22 14:28:01 +0000104 this->onCopyOnWrite(mode);
reed@google.com97af1a62012-08-28 12:19:02 +0000105 }
106
107 // regardless of copy-on-write, we must drop our cached image now, so
108 // that the next request will get our new contents.
109 fCachedImage->unref();
halcanary96fcdcc2015-08-27 07:41:13 -0700110 fCachedImage = nullptr;
reed26e0e582015-07-29 11:44:52 -0700111
112 if (unique) {
113 // Our content isn't held by any image now, so we can consider that content mutable.
114 // Raster surfaces need to be told it's safe to consider its pixels mutable again.
115 // We make this call after the ->unref() so the subclass can assert there are no images.
116 this->onRestoreBackingMutability();
117 }
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000118 } else if (kDiscard_ContentChangeMode == mode) {
119 this->onDiscard();
reed@google.com97af1a62012-08-28 12:19:02 +0000120 }
121}
122
123uint32_t SkSurface_Base::newGenerationID() {
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000124 SkASSERT(!fCachedCanvas || fCachedCanvas->getSurfaceBase() == this);
reed@google.com97af1a62012-08-28 12:19:02 +0000125 static int32_t gID;
126 return sk_atomic_inc(&gID) + 1;
127}
128
reed@google.com889b09e2012-07-27 21:10:42 +0000129static SkSurface_Base* asSB(SkSurface* surface) {
130 return static_cast<SkSurface_Base*>(surface);
131}
132
133///////////////////////////////////////////////////////////////////////////////
134
reed4a8126e2014-09-22 07:29:03 -0700135SkSurface::SkSurface(int width, int height, const SkSurfaceProps* props)
136 : fProps(SkSurfacePropsCopyOrDefault(props)), fWidth(width), fHeight(height)
137{
reedb2497c22014-12-31 12:31:43 -0800138 SkASSERT(fWidth > 0);
139 SkASSERT(fHeight > 0);
reed@google.com1360c522014-01-08 21:25:26 +0000140 fGenerationID = 0;
141}
142
reed4a8126e2014-09-22 07:29:03 -0700143SkSurface::SkSurface(const SkImageInfo& info, const SkSurfaceProps* props)
144 : fProps(SkSurfacePropsCopyOrDefault(props)), fWidth(info.width()), fHeight(info.height())
145{
reedb2497c22014-12-31 12:31:43 -0800146 SkASSERT(fWidth > 0);
147 SkASSERT(fHeight > 0);
reed@google.com889b09e2012-07-27 21:10:42 +0000148 fGenerationID = 0;
149}
150
reed@google.com97af1a62012-08-28 12:19:02 +0000151uint32_t SkSurface::generationID() {
152 if (0 == fGenerationID) {
153 fGenerationID = asSB(this)->newGenerationID();
154 }
155 return fGenerationID;
156}
157
commit-bot@chromium.orgc4c98702013-04-22 14:28:01 +0000158void SkSurface::notifyContentWillChange(ContentChangeMode mode) {
159 asSB(this)->aboutToDraw(mode);
reed@google.com97af1a62012-08-28 12:19:02 +0000160}
161
reed@google.com9ea5a3b2012-07-30 21:03:46 +0000162SkCanvas* SkSurface::getCanvas() {
163 return asSB(this)->getCachedCanvas();
reed@google.com889b09e2012-07-27 21:10:42 +0000164}
165
bsalomoneaaaf0b2015-01-23 08:08:04 -0800166SkImage* SkSurface::newImageSnapshot(Budgeted budgeted) {
bsalomonf47b9a32016-02-22 11:02:58 -0800167 // the caller will call unref() to balance this
168 return asSB(this)->refCachedImage(budgeted, kNo_ForceUnique);
169}
170
171SkImage* SkSurface::newImageSnapshot(Budgeted budgeted, ForceUnique unique) {
172 // the caller will call unref() to balance this
173 return asSB(this)->refCachedImage(budgeted, unique);
reed@google.com889b09e2012-07-27 21:10:42 +0000174}
175
reed@google.com2bd8b812013-11-01 13:46:54 +0000176SkSurface* SkSurface::newSurface(const SkImageInfo& info) {
mike@reedtribe.orgb9476252012-11-15 02:37:45 +0000177 return asSB(this)->onNewSurface(info);
reed@google.com889b09e2012-07-27 21:10:42 +0000178}
179
180void SkSurface::draw(SkCanvas* canvas, SkScalar x, SkScalar y,
181 const SkPaint* paint) {
182 return asSB(this)->onDraw(canvas, x, y, paint);
183}
commit-bot@chromium.orgc3bd8af2014-02-13 17:14:46 +0000184
185const void* SkSurface::peekPixels(SkImageInfo* info, size_t* rowBytes) {
186 return this->getCanvas()->peekPixels(info, rowBytes);
187}
reed4a8126e2014-09-22 07:29:03 -0700188
reed7543aa22014-12-09 14:39:44 -0800189bool SkSurface::readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
190 int srcX, int srcY) {
191 return this->getCanvas()->readPixels(dstInfo, dstPixels, dstRowBytes, srcX, srcY);
192}
193
joshualitt81793412015-07-08 12:54:04 -0700194GrBackendObject SkSurface::getTextureHandle(BackendHandleAccess access) {
reedfa5e68e2015-06-29 07:37:01 -0700195 return asSB(this)->onGetTextureHandle(access);
196}
197
joshualitt81793412015-07-08 12:54:04 -0700198bool SkSurface::getRenderTargetHandle(GrBackendObject* obj, BackendHandleAccess access) {
199 return asSB(this)->onGetRenderTargetHandle(obj, access);
200}
201
ericrkf7b8b8a2016-02-24 14:49:51 -0800202void SkSurface::prepareForExternalIO() {
203 asSB(this)->onPrepareForExternalIO();
204}
205
reed4a8126e2014-09-22 07:29:03 -0700206//////////////////////////////////////////////////////////////////////////////////////
reed4a8126e2014-09-22 07:29:03 -0700207
208#if !SK_SUPPORT_GPU
209
210SkSurface* SkSurface::NewRenderTargetDirect(GrRenderTarget*, const SkSurfaceProps*) {
halcanary96fcdcc2015-08-27 07:41:13 -0700211 return nullptr;
reed4a8126e2014-09-22 07:29:03 -0700212}
213
bsalomonafe30052015-01-16 07:32:33 -0800214SkSurface* SkSurface::NewRenderTarget(GrContext*, Budgeted, const SkImageInfo&, int,
erikchen9a1ed5d2016-02-10 16:32:34 -0800215 const SkSurfaceProps*, GrTextureStorageAllocator) {
halcanary96fcdcc2015-08-27 07:41:13 -0700216 return nullptr;
reed4a8126e2014-09-22 07:29:03 -0700217}
218
bsalomond3e259a2015-06-30 12:04:40 -0700219SkSurface* SkSurface::NewFromBackendTexture(GrContext*, const GrBackendTextureDesc&,
bsalomone4579ad2015-04-08 08:38:40 -0700220 const SkSurfaceProps*) {
halcanary96fcdcc2015-08-27 07:41:13 -0700221 return nullptr;
bsalomone4579ad2015-04-08 08:38:40 -0700222}
reed4a8126e2014-09-22 07:29:03 -0700223
bsalomond3e259a2015-06-30 12:04:40 -0700224SkSurface* SkSurface::NewFromBackendRenderTarget(GrContext*, const GrBackendRenderTargetDesc&,
225 const SkSurfaceProps*) {
halcanary96fcdcc2015-08-27 07:41:13 -0700226 return nullptr;
bsalomond3e259a2015-06-30 12:04:40 -0700227}
228
ericrkf7b8b8a2016-02-24 14:49:51 -0800229SkSurface* NewFromBackendTextureAsRenderTarget(GrContext*, const GrBackendTextureDesc&,
230 const SkSurfaceProps*) {
231 return nullptr;
232}
233
reed4a8126e2014-09-22 07:29:03 -0700234#endif