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 #include "SkGpuDevice.h"
12
13 class SkSurface_Gpu : public SkSurface_Base {
14 public:
15 SK_DECLARE_INST_COUNT(SkSurface_Gpu)
16
17 SkSurface_Gpu(GrRenderTarget*, bool cached, const SkSurfaceProps*, bool doClear);
18 virtual ~SkSurface_Gpu();
19
20 virtual SkCanvas* onNewCanvas() SK_OVERRIDE;
21 virtual SkSurface* onNewSurface(const SkImageInfo&) SK_OVERRIDE;
22 virtual SkImage* onNewImageSnapshot() SK_OVERRIDE;
23 virtual void onDraw(SkCanvas*, SkScalar x, SkScalar y,
24 const SkPaint*) SK_OVERRIDE;
25 virtual void onCopyOnWrite(ContentChangeMode) SK_OVERRIDE;
26 virtual void onDiscard() SK_OVERRIDE;
27
28 private:
29 SkGpuDevice* fDevice;
30
31 typedef SkSurface_Base INHERITED;
32 };
33
34 ///////////////////////////////////////////////////////////////////////////////
35
SkSurface_Gpu(GrRenderTarget * renderTarget,bool cached,const SkSurfaceProps * props,bool doClear)36 SkSurface_Gpu::SkSurface_Gpu(GrRenderTarget* renderTarget, bool cached, const SkSurfaceProps* props,
37 bool doClear)
38 : INHERITED(renderTarget->width(), renderTarget->height(), props)
39 {
40 int deviceFlags = 0;
41 deviceFlags |= cached ? SkGpuDevice::kCached_Flag : 0;
42 deviceFlags |= this->props().isUseDistanceFieldFonts() ? SkGpuDevice::kDFFonts_Flag : 0;
43 fDevice = SkGpuDevice::Create(renderTarget, this->props(), deviceFlags);
44
45 if (kRGB_565_GrPixelConfig != renderTarget->config() && doClear) {
46 fDevice->clear(0x0);
47 }
48 }
49
~SkSurface_Gpu()50 SkSurface_Gpu::~SkSurface_Gpu() {
51 SkSafeUnref(fDevice);
52 }
53
onNewCanvas()54 SkCanvas* SkSurface_Gpu::onNewCanvas() {
55 SkCanvas::InitFlags flags = SkCanvas::kDefault_InitFlags;
56 // When we think this works...
57 // flags |= SkCanvas::kConservativeRasterClip_InitFlag;
58
59 return SkNEW_ARGS(SkCanvas, (fDevice, &this->props(), flags));
60 }
61
onNewSurface(const SkImageInfo & info)62 SkSurface* SkSurface_Gpu::onNewSurface(const SkImageInfo& info) {
63 GrRenderTarget* rt = fDevice->accessRenderTarget();
64 int sampleCount = rt->numSamples();
65 return SkSurface::NewRenderTarget(fDevice->context(), info, sampleCount, &this->props());
66 }
67
onNewImageSnapshot()68 SkImage* SkSurface_Gpu::onNewImageSnapshot() {
69 return SkImage::NewTexture(fDevice->accessBitmap(false));
70 }
71
onDraw(SkCanvas * canvas,SkScalar x,SkScalar y,const SkPaint * paint)72 void SkSurface_Gpu::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y,
73 const SkPaint* paint) {
74 canvas->drawBitmap(fDevice->accessBitmap(false), x, y, paint);
75 }
76
77 // Create a new SkGpuDevice and, if necessary, copy the contents of the old
78 // device into it. Note that this flushes the SkGpuDevice but
79 // doesn't force an OpenGL flush.
onCopyOnWrite(ContentChangeMode mode)80 void SkSurface_Gpu::onCopyOnWrite(ContentChangeMode mode) {
81 GrRenderTarget* rt = fDevice->accessRenderTarget();
82 // are we sharing our render target with the image?
83 SkASSERT(this->getCachedImage());
84 if (rt->asTexture() == SkTextureImageGetTexture(this->getCachedImage())) {
85 // We call createCompatibleDevice because it uses the texture cache. This isn't
86 // necessarily correct (http://skbug.com/2252), but never using the cache causes
87 // a Chromium regression. (http://crbug.com/344020)
88 SkGpuDevice* newDevice = static_cast<SkGpuDevice*>(
89 fDevice->createCompatibleDevice(fDevice->imageInfo()));
90 SkAutoTUnref<SkGpuDevice> aurd(newDevice);
91 if (kRetain_ContentChangeMode == mode) {
92 fDevice->context()->copyTexture(rt->asTexture(), newDevice->accessRenderTarget());
93 }
94 SkASSERT(this->getCachedCanvas());
95 SkASSERT(this->getCachedCanvas()->getDevice() == fDevice);
96
97 this->getCachedCanvas()->setRootDevice(newDevice);
98 SkRefCnt_SafeAssign(fDevice, newDevice);
99 } else if (kDiscard_ContentChangeMode == mode) {
100 this->SkSurface_Gpu::onDiscard();
101 }
102 }
103
onDiscard()104 void SkSurface_Gpu::onDiscard() {
105 fDevice->accessRenderTarget()->discard();
106 }
107
108 ///////////////////////////////////////////////////////////////////////////////
109
NewRenderTargetDirect(GrRenderTarget * target,const SkSurfaceProps * props)110 SkSurface* SkSurface::NewRenderTargetDirect(GrRenderTarget* target, const SkSurfaceProps* props) {
111 if (NULL == target) {
112 return NULL;
113 }
114 return SkNEW_ARGS(SkSurface_Gpu, (target, false, props, false));
115 }
116
NewRenderTarget(GrContext * ctx,const SkImageInfo & info,int sampleCount,const SkSurfaceProps * props)117 SkSurface* SkSurface::NewRenderTarget(GrContext* ctx, const SkImageInfo& info, int sampleCount,
118 const SkSurfaceProps* props) {
119 if (NULL == ctx) {
120 return NULL;
121 }
122
123 GrTextureDesc desc;
124 desc.fFlags = kRenderTarget_GrTextureFlagBit | kCheckAllocation_GrTextureFlagBit;
125 desc.fWidth = info.width();
126 desc.fHeight = info.height();
127 desc.fConfig = SkImageInfo2GrPixelConfig(info);
128 desc.fSampleCnt = sampleCount;
129
130 SkAutoTUnref<GrTexture> tex(ctx->createUncachedTexture(desc, NULL, 0));
131 if (NULL == tex) {
132 return NULL;
133 }
134
135 return SkNEW_ARGS(SkSurface_Gpu, (tex->asRenderTarget(), false, props, true));
136 }
137
NewScratchRenderTarget(GrContext * ctx,const SkImageInfo & info,int sampleCount,const SkSurfaceProps * props)138 SkSurface* SkSurface::NewScratchRenderTarget(GrContext* ctx, const SkImageInfo& info,
139 int sampleCount, const SkSurfaceProps* props) {
140 if (NULL == ctx) {
141 return NULL;
142 }
143
144 GrTextureDesc desc;
145 desc.fFlags = kRenderTarget_GrTextureFlagBit | kCheckAllocation_GrTextureFlagBit;
146 desc.fWidth = info.width();
147 desc.fHeight = info.height();
148 desc.fConfig = SkImageInfo2GrPixelConfig(info);
149 desc.fSampleCnt = sampleCount;
150
151 SkAutoTUnref<GrTexture> tex(ctx->lockAndRefScratchTexture(desc, GrContext::kExact_ScratchTexMatch));
152
153 if (NULL == tex) {
154 return NULL;
155 }
156
157 return SkNEW_ARGS(SkSurface_Gpu, (tex->asRenderTarget(), true, props, true));
158 }
159