|
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*); |
|
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 |
|
27 private: |
|
28 SkGpuDevice* fDevice; |
|
29 |
|
30 typedef SkSurface_Base INHERITED; |
|
31 }; |
|
32 |
|
33 /////////////////////////////////////////////////////////////////////////////// |
|
34 |
|
35 SkSurface_Gpu::SkSurface_Gpu(GrRenderTarget* renderTarget) |
|
36 : INHERITED(renderTarget->width(), renderTarget->height()) { |
|
37 fDevice = SkNEW_ARGS(SkGpuDevice, (renderTarget->getContext(), renderTarget)); |
|
38 |
|
39 if (kRGB_565_GrPixelConfig != renderTarget->config()) { |
|
40 fDevice->clear(0x0); |
|
41 } |
|
42 } |
|
43 |
|
44 SkSurface_Gpu::~SkSurface_Gpu() { |
|
45 SkSafeUnref(fDevice); |
|
46 } |
|
47 |
|
48 SkCanvas* SkSurface_Gpu::onNewCanvas() { |
|
49 return SkNEW_ARGS(SkCanvas, (fDevice)); |
|
50 } |
|
51 |
|
52 SkSurface* SkSurface_Gpu::onNewSurface(const SkImageInfo& info) { |
|
53 GrRenderTarget* rt = fDevice->accessRenderTarget(); |
|
54 int sampleCount = rt->numSamples(); |
|
55 return SkSurface::NewRenderTarget(fDevice->context(), info, sampleCount); |
|
56 } |
|
57 |
|
58 SkImage* SkSurface_Gpu::onNewImageSnapshot() { |
|
59 return SkImage::NewTexture(fDevice->accessBitmap(false)); |
|
60 } |
|
61 |
|
62 void SkSurface_Gpu::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, |
|
63 const SkPaint* paint) { |
|
64 canvas->drawBitmap(fDevice->accessBitmap(false), x, y, paint); |
|
65 } |
|
66 |
|
67 // Create a new SkGpuDevice and, if necessary, copy the contents of the old |
|
68 // device into it. Note that this flushes the SkGpuDevice but |
|
69 // doesn't force an OpenGL flush. |
|
70 void SkSurface_Gpu::onCopyOnWrite(ContentChangeMode mode) { |
|
71 GrRenderTarget* rt = fDevice->accessRenderTarget(); |
|
72 // are we sharing our render target with the image? |
|
73 SkASSERT(NULL != this->getCachedImage()); |
|
74 if (rt->asTexture() == SkTextureImageGetTexture(this->getCachedImage())) { |
|
75 // We call createCompatibleDevice because it uses the texture cache. This isn't |
|
76 // necessarily correct (http://skbug.com/2252), but never using the cache causes |
|
77 // a Chromium regression. (http://crbug.com/344020) |
|
78 SkGpuDevice* newDevice = static_cast<SkGpuDevice*>( |
|
79 fDevice->createCompatibleDevice(fDevice->imageInfo())); |
|
80 SkAutoTUnref<SkGpuDevice> aurd(newDevice); |
|
81 if (kRetain_ContentChangeMode == mode) { |
|
82 fDevice->context()->copyTexture(rt->asTexture(), newDevice->accessRenderTarget()); |
|
83 } |
|
84 SkASSERT(NULL != this->getCachedCanvas()); |
|
85 SkASSERT(this->getCachedCanvas()->getDevice() == fDevice); |
|
86 |
|
87 this->getCachedCanvas()->setRootDevice(newDevice); |
|
88 SkRefCnt_SafeAssign(fDevice, newDevice); |
|
89 } |
|
90 } |
|
91 |
|
92 /////////////////////////////////////////////////////////////////////////////// |
|
93 |
|
94 SkSurface* SkSurface::NewRenderTargetDirect(GrRenderTarget* target) { |
|
95 if (NULL == target) { |
|
96 return NULL; |
|
97 } |
|
98 return SkNEW_ARGS(SkSurface_Gpu, (target)); |
|
99 } |
|
100 |
|
101 SkSurface* SkSurface::NewRenderTarget(GrContext* ctx, const SkImageInfo& info, int sampleCount) { |
|
102 if (NULL == ctx) { |
|
103 return NULL; |
|
104 } |
|
105 |
|
106 SkBitmap::Config config = SkImageInfoToBitmapConfig(info); |
|
107 |
|
108 GrTextureDesc desc; |
|
109 desc.fFlags = kRenderTarget_GrTextureFlagBit | kCheckAllocation_GrTextureFlagBit; |
|
110 desc.fWidth = info.fWidth; |
|
111 desc.fHeight = info.fHeight; |
|
112 desc.fConfig = SkBitmapConfig2GrPixelConfig(config); |
|
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())); |
|
121 } |