1 /*
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
8 #include "SkSurface_Base.h"
9 #include "SkImagePriv.h"
10 #include "SkCanvas.h"
11
12 #include "SkFontLCDConfig.h"
compute_default_geometry()13 static 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
SkSurfaceProps()37 SkSurfaceProps::SkSurfaceProps() : fFlags(0), fPixelGeometry(kUnknown_SkPixelGeometry) {}
38
SkSurfaceProps(InitType)39 SkSurfaceProps::SkSurfaceProps(InitType) : fFlags(0), fPixelGeometry(compute_default_geometry()) {}
40
SkSurfaceProps(uint32_t flags,InitType)41 SkSurfaceProps::SkSurfaceProps(uint32_t flags, InitType)
42 : fFlags(flags)
43 , fPixelGeometry(compute_default_geometry())
44 {}
45
SkSurfaceProps(uint32_t flags,SkPixelGeometry pg)46 SkSurfaceProps::SkSurfaceProps(uint32_t flags, SkPixelGeometry pg)
47 : fFlags(flags), fPixelGeometry(pg)
48 {}
49
SkSurfaceProps(const SkSurfaceProps & other)50 SkSurfaceProps::SkSurfaceProps(const SkSurfaceProps& other)
51 : fFlags(other.fFlags)
52 , fPixelGeometry(other.fPixelGeometry)
53 {}
54
55 ///////////////////////////////////////////////////////////////////////////////
56
SkSurface_Base(int width,int height,const SkSurfaceProps * props)57 SkSurface_Base::SkSurface_Base(int width, int height, const SkSurfaceProps* props)
58 : INHERITED(width, height, props)
59 {
60 fCachedCanvas = NULL;
61 fCachedImage = NULL;
62 }
63
SkSurface_Base(const SkImageInfo & info,const SkSurfaceProps * props)64 SkSurface_Base::SkSurface_Base(const SkImageInfo& info, const SkSurfaceProps* props)
65 : INHERITED(info, props)
66 {
67 fCachedCanvas = NULL;
68 fCachedImage = NULL;
69 }
70
~SkSurface_Base()71 SkSurface_Base::~SkSurface_Base() {
72 // in case the canvas outsurvives us, we null the callback
73 if (fCachedCanvas) {
74 fCachedCanvas->setSurfaceBase(NULL);
75 }
76
77 SkSafeUnref(fCachedImage);
78 SkSafeUnref(fCachedCanvas);
79 }
80
onDraw(SkCanvas * canvas,SkScalar x,SkScalar y,const SkPaint * paint)81 void SkSurface_Base::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint) {
82 SkImage* image = this->newImageSnapshot(kYes_Budgeted);
83 if (image) {
84 canvas->drawImage(image, x, y, paint);
85 image->unref();
86 }
87 }
88
aboutToDraw(ContentChangeMode mode)89 void SkSurface_Base::aboutToDraw(ContentChangeMode mode) {
90 this->dirtyGenerationID();
91
92 SkASSERT(!fCachedCanvas || fCachedCanvas->getSurfaceBase() == this);
93
94 if (fCachedImage) {
95 // the surface may need to fork its backend, if its sharing it with
96 // the cached image. Note: we only call if there is an outstanding owner
97 // on the image (besides us).
98 if (!fCachedImage->unique()) {
99 this->onCopyOnWrite(mode);
100 }
101
102 // regardless of copy-on-write, we must drop our cached image now, so
103 // that the next request will get our new contents.
104 fCachedImage->unref();
105 fCachedImage = NULL;
106 } else if (kDiscard_ContentChangeMode == mode) {
107 this->onDiscard();
108 }
109 }
110
newGenerationID()111 uint32_t SkSurface_Base::newGenerationID() {
112 SkASSERT(!fCachedCanvas || fCachedCanvas->getSurfaceBase() == this);
113 static int32_t gID;
114 return sk_atomic_inc(&gID) + 1;
115 }
116
asSB(SkSurface * surface)117 static SkSurface_Base* asSB(SkSurface* surface) {
118 return static_cast<SkSurface_Base*>(surface);
119 }
120
121 ///////////////////////////////////////////////////////////////////////////////
122
SkSurface(int width,int height,const SkSurfaceProps * props)123 SkSurface::SkSurface(int width, int height, const SkSurfaceProps* props)
124 : fProps(SkSurfacePropsCopyOrDefault(props)), fWidth(width), fHeight(height)
125 {
126 SkASSERT(fWidth > 0);
127 SkASSERT(fHeight > 0);
128 fGenerationID = 0;
129 }
130
SkSurface(const SkImageInfo & info,const SkSurfaceProps * props)131 SkSurface::SkSurface(const SkImageInfo& info, const SkSurfaceProps* props)
132 : fProps(SkSurfacePropsCopyOrDefault(props)), fWidth(info.width()), fHeight(info.height())
133 {
134 SkASSERT(fWidth > 0);
135 SkASSERT(fHeight > 0);
136 fGenerationID = 0;
137 }
138
generationID()139 uint32_t SkSurface::generationID() {
140 if (0 == fGenerationID) {
141 fGenerationID = asSB(this)->newGenerationID();
142 }
143 return fGenerationID;
144 }
145
notifyContentWillChange(ContentChangeMode mode)146 void SkSurface::notifyContentWillChange(ContentChangeMode mode) {
147 asSB(this)->aboutToDraw(mode);
148 }
149
getCanvas()150 SkCanvas* SkSurface::getCanvas() {
151 return asSB(this)->getCachedCanvas();
152 }
153
newImageSnapshot(Budgeted budgeted)154 SkImage* SkSurface::newImageSnapshot(Budgeted budgeted) {
155 SkImage* image = asSB(this)->getCachedImage(budgeted);
156 SkSafeRef(image); // the caller will call unref() to balance this
157 return image;
158 }
159
newSurface(const SkImageInfo & info)160 SkSurface* SkSurface::newSurface(const SkImageInfo& info) {
161 return asSB(this)->onNewSurface(info);
162 }
163
draw(SkCanvas * canvas,SkScalar x,SkScalar y,const SkPaint * paint)164 void SkSurface::draw(SkCanvas* canvas, SkScalar x, SkScalar y,
165 const SkPaint* paint) {
166 return asSB(this)->onDraw(canvas, x, y, paint);
167 }
168
peekPixels(SkImageInfo * info,size_t * rowBytes)169 const void* SkSurface::peekPixels(SkImageInfo* info, size_t* rowBytes) {
170 return this->getCanvas()->peekPixels(info, rowBytes);
171 }
172
readPixels(const SkImageInfo & dstInfo,void * dstPixels,size_t dstRowBytes,int srcX,int srcY)173 bool SkSurface::readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
174 int srcX, int srcY) {
175 return this->getCanvas()->readPixels(dstInfo, dstPixels, dstRowBytes, srcX, srcY);
176 }
177
178 //////////////////////////////////////////////////////////////////////////////////////
179
180 #if !SK_SUPPORT_GPU
181
NewRenderTargetDirect(GrRenderTarget *,const SkSurfaceProps *)182 SkSurface* SkSurface::NewRenderTargetDirect(GrRenderTarget*, const SkSurfaceProps*) {
183 return NULL;
184 }
185
NewRenderTarget(GrContext *,Budgeted,const SkImageInfo &,int,const SkSurfaceProps *)186 SkSurface* SkSurface::NewRenderTarget(GrContext*, Budgeted, const SkImageInfo&, int,
187 const SkSurfaceProps*) {
188 return NULL;
189 }
190
NewWrappedRenderTarget(GrContext *,GrBackendTextureDesc,const SkSurfaceProps *)191 SkSurface* SkSurface::NewWrappedRenderTarget(GrContext*, GrBackendTextureDesc,
192 const SkSurfaceProps*) {
193 return NULL;
194 }
195
196 #endif
197