OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 Google Inc. |
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 "SkSurface_Base.h" | 8 #include "SkSurface_Gpu.h" |
9 #include "SkImagePriv.h" | 9 |
10 #include "SkImage_Base.h" | 10 #include "GrGpuResourceCacheAccess.h" |
11 #include "SkCanvas.h" | 11 #include "SkCanvas.h" |
12 #include "SkGpuDevice.h" | 12 #include "SkGpuDevice.h" |
13 #include "SkSurface_Gpu.h" | 13 #include "SkImage_Base.h" |
14 #include "SkImagePriv.h" | |
15 #include "SkSurface_Base.h" | |
14 | 16 |
15 #if SK_SUPPORT_GPU | 17 #if SK_SUPPORT_GPU |
16 | 18 |
17 /////////////////////////////////////////////////////////////////////////////// | 19 /////////////////////////////////////////////////////////////////////////////// |
18 | 20 |
19 SkSurface_Gpu::SkSurface_Gpu(GrRenderTarget* renderTarget, const SkSurfaceProps* props, | 21 SkSurface_Gpu::SkSurface_Gpu(SkGpuDevice* device) |
20 bool doClear) | 22 : INHERITED(device->width(), device->height(), &device->surfaceProps()) |
21 : INHERITED(renderTarget->width(), renderTarget->height(), props) { | 23 , fDevice(SkRef(device)) { |
22 int deviceFlags = 0; | |
23 deviceFlags |= this->props().isUseDistanceFieldFonts() ? SkGpuDevice::kDFTex t_Flag : 0; | |
24 fDevice = SkGpuDevice::Create(renderTarget, this->props(), deviceFlags); | |
25 | |
26 if (kRGB_565_GrPixelConfig != renderTarget->config() && doClear) { | |
27 fDevice->clearAll(); | |
28 } | |
29 } | 24 } |
30 | 25 |
31 SkSurface_Gpu::~SkSurface_Gpu() { | 26 SkSurface_Gpu::~SkSurface_Gpu() { |
32 SkSafeUnref(fDevice); | 27 SkSafeUnref(fDevice); |
33 } | 28 } |
34 | 29 |
35 SkCanvas* SkSurface_Gpu::onNewCanvas() { | 30 SkCanvas* SkSurface_Gpu::onNewCanvas() { |
36 SkCanvas::InitFlags flags = SkCanvas::kDefault_InitFlags; | 31 SkCanvas::InitFlags flags = SkCanvas::kDefault_InitFlags; |
37 // When we think this works... | 32 // When we think this works... |
38 // flags |= SkCanvas::kConservativeRasterClip_InitFlag; | 33 // flags |= SkCanvas::kConservativeRasterClip_InitFlag; |
39 | 34 |
40 return SkNEW_ARGS(SkCanvas, (fDevice, &this->props(), flags)); | 35 return SkNEW_ARGS(SkCanvas, (fDevice, &this->props(), flags)); |
41 } | 36 } |
42 | 37 |
43 SkSurface* SkSurface_Gpu::onNewSurface(const SkImageInfo& info) { | 38 SkSurface* SkSurface_Gpu::onNewSurface(const SkImageInfo& info) { |
44 GrRenderTarget* rt = fDevice->accessRenderTarget(); | 39 GrRenderTarget* rt = fDevice->accessRenderTarget(); |
45 int sampleCount = rt->numSamples(); | 40 int sampleCount = rt->numSamples(); |
46 return SkSurface::NewRenderTarget(fDevice->context(), info, sampleCount, &th is->props()); | 41 // TODO: Make caller specify this (change virtual signature of onNewSurface) . |
42 static const Budgeted kBudgeted = kNo_Budgeted; | |
43 return SkSurface::NewRenderTarget(fDevice->context(), kBudgeted, info, sampl eCount, | |
44 &this->props()); | |
47 } | 45 } |
48 | 46 |
49 SkImage* SkSurface_Gpu::onNewImageSnapshot() { | 47 SkImage* SkSurface_Gpu::onNewImageSnapshot() { |
50 const int sampleCount = fDevice->accessRenderTarget()->numSamples(); | 48 const int sampleCount = fDevice->accessRenderTarget()->numSamples(); |
51 SkImage* image = SkNewImageFromBitmapTexture(fDevice->accessBitmap(false), s ampleCount); | 49 SkImage* image = SkNewImageFromBitmapTexture(fDevice->accessBitmap(false), s ampleCount); |
52 if (image) { | 50 if (image) { |
53 as_IB(image)->initWithProps(this->props()); | 51 as_IB(image)->initWithProps(this->props()); |
54 } | 52 } |
55 return image; | 53 return image; |
56 } | 54 } |
57 | 55 |
58 void SkSurface_Gpu::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, | 56 void SkSurface_Gpu::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, |
59 const SkPaint* paint) { | 57 const SkPaint* paint) { |
60 canvas->drawBitmap(fDevice->accessBitmap(false), x, y, paint); | 58 canvas->drawBitmap(fDevice->accessBitmap(false), x, y, paint); |
61 } | 59 } |
62 | 60 |
63 // Create a new SkGpuDevice and, if necessary, copy the contents of the old | 61 // Create a new SkGpuDevice and, if necessary, copy the contents of the old |
64 // device into it. Note that this flushes the SkGpuDevice but | 62 // device into it. Note that this flushes the SkGpuDevice but |
65 // doesn't force an OpenGL flush. | 63 // doesn't force an OpenGL flush. |
66 void SkSurface_Gpu::onCopyOnWrite(ContentChangeMode mode) { | 64 void SkSurface_Gpu::onCopyOnWrite(ContentChangeMode mode) { |
67 GrRenderTarget* rt = fDevice->accessRenderTarget(); | 65 GrRenderTarget* rt = fDevice->accessRenderTarget(); |
68 // are we sharing our render target with the image? | 66 // are we sharing our render target with the image? |
69 SkASSERT(this->getCachedImage()); | 67 SkASSERT(this->getCachedImage()); |
70 if (rt->asTexture() == SkTextureImageGetTexture(this->getCachedImage())) { | 68 if (rt->asTexture() == SkTextureImageGetTexture(this->getCachedImage())) { |
71 // We call createCompatibleDevice because it uses the texture cache. Thi s isn't | 69 GrRenderTarget* oldRT = this->fDevice->accessRenderTarget(); |
72 // necessarily correct (http://skbug.com/2252), but never using the cach e causes | 70 SkSurface::Budgeted budgeted = oldRT->cacheAccess().isBudgeted() ? kYes_ Budgeted : |
73 // a Chromium regression. (http://crbug.com/344020) | 71 kNo_B udgeted; |
74 SkGpuDevice* newDevice = fDevice->cloneDevice(this->props()); | 72 SkAutoTUnref<SkGpuDevice> newDevice( |
75 SkAutoTUnref<SkGpuDevice> aurd(newDevice); | 73 SkGpuDevice::Create(oldRT->getContext(), budgeted, fDevice->imageInf o(), |
robertphillips
2015/01/15 21:30:36
tab this over ?
bsalomon
2015/01/15 22:15:50
Done.
| |
76 if (kRetain_ContentChangeMode == mode) { | 74 oldRT->numSamples(), &this->props(), 0)); |
77 fDevice->context()->copySurface(newDevice->accessRenderTarget(), rt- >asTexture()); | 75 |
robertphillips
2015/01/15 21:30:36
What happened to kRetain_ContentChangeMode?
bsalomon
2015/01/15 22:15:50
eek, it's back.
| |
78 } | |
79 SkASSERT(this->getCachedCanvas()); | 76 SkASSERT(this->getCachedCanvas()); |
80 SkASSERT(this->getCachedCanvas()->getDevice() == fDevice); | 77 SkASSERT(this->getCachedCanvas()->getDevice() == fDevice); |
81 | 78 |
82 this->getCachedCanvas()->setRootDevice(newDevice); | 79 this->getCachedCanvas()->setRootDevice(newDevice); |
83 SkRefCnt_SafeAssign(fDevice, newDevice); | 80 SkRefCnt_SafeAssign(fDevice, newDevice.get()); |
81 | |
82 // For now we always treat the image snapshots as budgeted. We could mak e newImageSnapshot | |
83 // take a Budgeted param. | |
84 oldRT->cacheAccess().makeBudgeted(); | |
85 | |
84 } else if (kDiscard_ContentChangeMode == mode) { | 86 } else if (kDiscard_ContentChangeMode == mode) { |
85 this->SkSurface_Gpu::onDiscard(); | 87 this->SkSurface_Gpu::onDiscard(); |
86 } | 88 } |
87 } | 89 } |
88 | 90 |
89 void SkSurface_Gpu::onDiscard() { | 91 void SkSurface_Gpu::onDiscard() { |
90 fDevice->accessRenderTarget()->discard(); | 92 fDevice->accessRenderTarget()->discard(); |
91 } | 93 } |
92 | 94 |
93 /////////////////////////////////////////////////////////////////////////////// | 95 /////////////////////////////////////////////////////////////////////////////// |
94 | 96 |
95 SkSurface* SkSurface::NewRenderTargetDirect(GrRenderTarget* target, const SkSurf aceProps* props) { | 97 SkSurface* SkSurface::NewRenderTargetDirect(GrRenderTarget* target, const SkSurf aceProps* props) { |
96 if (NULL == target) { | 98 SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(target, props)); |
99 if (!device) { | |
97 return NULL; | 100 return NULL; |
98 } | 101 } |
99 return SkNEW_ARGS(SkSurface_Gpu, (target, props, false)); | 102 return SkNEW_ARGS(SkSurface_Gpu, (device)); |
100 } | 103 } |
101 | 104 |
102 SkSurface* SkSurface::NewRenderTarget(GrContext* ctx, const SkImageInfo& info, i nt sampleCount, | 105 SkSurface* SkSurface::NewRenderTarget(GrContext* ctx, Budgeted budgeted, const S kImageInfo& info, |
103 const SkSurfaceProps* props) { | 106 int sampleCount, const SkSurfaceProps* pro ps) { |
104 if (NULL == ctx) { | 107 SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(ctx, budgeted, info, sa mpleCount, props, |
108 SkGpuDevice::kNeedClear _Flag)); | |
109 if (!device) { | |
105 return NULL; | 110 return NULL; |
106 } | 111 } |
107 | 112 return SkNEW_ARGS(SkSurface_Gpu, (device)); |
108 GrSurfaceDesc desc; | |
109 desc.fFlags = kRenderTarget_GrSurfaceFlag | kCheckAllocation_GrSurfaceFlag; | |
110 desc.fWidth = info.width(); | |
111 desc.fHeight = info.height(); | |
112 desc.fConfig = SkImageInfo2GrPixelConfig(info); | |
113 desc.fSampleCnt = sampleCount; | |
114 | |
115 SkAutoTUnref<GrTexture> tex(ctx->createUncachedTexture(desc, NULL, 0)); | |
116 if (NULL == tex) { | |
117 return NULL; | |
118 } | |
119 | |
120 return SkNEW_ARGS(SkSurface_Gpu, (tex->asRenderTarget(), props, true)); | |
121 } | |
122 | |
123 SkSurface* SkSurface::NewScratchRenderTarget(GrContext* ctx, const SkImageInfo& info, | |
124 int sampleCount, const SkSurfacePro ps* props) { | |
125 if (NULL == ctx) { | |
126 return NULL; | |
127 } | |
128 | |
129 GrSurfaceDesc desc; | |
130 desc.fFlags = kRenderTarget_GrSurfaceFlag | kCheckAllocation_GrSurfaceFlag; | |
131 desc.fWidth = info.width(); | |
132 desc.fHeight = info.height(); | |
133 desc.fConfig = SkImageInfo2GrPixelConfig(info); | |
134 desc.fSampleCnt = sampleCount; | |
135 | |
136 SkAutoTUnref<GrTexture> tex(ctx->refScratchTexture(desc, GrContext::kExact_S cratchTexMatch)); | |
137 | |
138 if (NULL == tex) { | |
139 return NULL; | |
140 } | |
141 | |
142 return SkNEW_ARGS(SkSurface_Gpu, (tex->asRenderTarget(), props, true)); | |
143 } | 113 } |
144 | 114 |
145 #endif | 115 #endif |
OLD | NEW |