blob: 54c74b2babc035f06036bee356368634a9cf887f [file] [log] [blame]
reed@google.com5d4ba882012-07-31 15:45:27 +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
8#include "SkSurface_Base.h"
9#include "SkImagePriv.h"
10#include "SkCanvas.h"
robertphillips@google.com97b6b072012-10-31 14:48:39 +000011#include "SkGpuDevice.h"
reed@google.com5d4ba882012-07-31 15:45:27 +000012
13class SkSurface_Gpu : public SkSurface_Base {
14public:
robertphillips@google.com97b6b072012-10-31 14:48:39 +000015 SK_DECLARE_INST_COUNT(SkSurface_Gpu)
reed@google.com5d4ba882012-07-31 15:45:27 +000016
robertphillips@google.com97b6b072012-10-31 14:48:39 +000017 SkSurface_Gpu(GrContext*, const SkImage::Info&, int sampleCount);
18 SkSurface_Gpu(GrContext*, GrRenderTarget*);
19 virtual ~SkSurface_Gpu();
reed@google.com5d4ba882012-07-31 15:45:27 +000020
21 virtual SkCanvas* onNewCanvas() SK_OVERRIDE;
22 virtual SkSurface* onNewSurface(const SkImage::Info&, SkColorSpace*) SK_OVERRIDE;
23 virtual SkImage* onNewImageShapshot() SK_OVERRIDE;
24 virtual void onDraw(SkCanvas*, SkScalar x, SkScalar y,
25 const SkPaint*) SK_OVERRIDE;
robertphillips@google.com97b6b072012-10-31 14:48:39 +000026 virtual void onCopyOnWrite(SkImage*, SkCanvas*) SK_OVERRIDE;
reed@google.com5d4ba882012-07-31 15:45:27 +000027
28private:
robertphillips@google.com97b6b072012-10-31 14:48:39 +000029 SkGpuDevice* fDevice;
reed@google.com5d4ba882012-07-31 15:45:27 +000030
31 typedef SkSurface_Base INHERITED;
32};
33
robertphillips@google.com97b6b072012-10-31 14:48:39 +000034SK_DEFINE_INST_COUNT(SkSurface_Gpu)
35
reed@google.com5d4ba882012-07-31 15:45:27 +000036///////////////////////////////////////////////////////////////////////////////
37
robertphillips@google.com97b6b072012-10-31 14:48:39 +000038SkSurface_Gpu::SkSurface_Gpu(GrContext* ctx, const SkImage::Info& info,
39 int sampleCount)
reed@google.com5d4ba882012-07-31 15:45:27 +000040 : INHERITED(info.fWidth, info.fHeight) {
41 bool isOpaque;
42 SkBitmap::Config config = SkImageInfoToBitmapConfig(info, &isOpaque);
rmistry@google.comfbfcd562012-08-23 18:09:54 +000043
robertphillips@google.com97b6b072012-10-31 14:48:39 +000044 fDevice = SkNEW_ARGS(SkGpuDevice, (ctx, config, info.fWidth, info.fHeight, sampleCount));
robertphillips@google.comea5d8af2012-11-02 17:38:28 +000045
46 if (!isOpaque) {
47 fDevice->clear(0x0);
48 }
reed@google.com5d4ba882012-07-31 15:45:27 +000049}
50
robertphillips@google.com97b6b072012-10-31 14:48:39 +000051SkSurface_Gpu::SkSurface_Gpu(GrContext* ctx, GrRenderTarget* renderTarget)
52 : INHERITED(renderTarget->width(), renderTarget->height()) {
53 fDevice = SkNEW_ARGS(SkGpuDevice, (ctx, renderTarget));
robertphillips@google.comea5d8af2012-11-02 17:38:28 +000054
55 if (kRGB_565_GrPixelConfig != renderTarget->config()) {
56 fDevice->clear(0x0);
57 }
robertphillips@google.com97b6b072012-10-31 14:48:39 +000058}
reed@google.com5d4ba882012-07-31 15:45:27 +000059
robertphillips@google.com97b6b072012-10-31 14:48:39 +000060SkSurface_Gpu::~SkSurface_Gpu() {
61 SkSafeUnref(fDevice);
reed@google.com5d4ba882012-07-31 15:45:27 +000062}
63
64SkCanvas* SkSurface_Gpu::onNewCanvas() {
robertphillips@google.com97b6b072012-10-31 14:48:39 +000065 return SkNEW_ARGS(SkCanvas, (fDevice));
reed@google.com5d4ba882012-07-31 15:45:27 +000066}
67
68SkSurface* SkSurface_Gpu::onNewSurface(const SkImage::Info& info,
robertphillips@google.com97b6b072012-10-31 14:48:39 +000069 SkColorSpace* cs) {
70 GrRenderTarget* rt = (GrRenderTarget*) fDevice->accessRenderTarget();
71 int sampleCount = rt->numSamples();
72 return SkSurface::NewRenderTarget(fDevice->context(), info, NULL, sampleCount);
reed@google.com5d4ba882012-07-31 15:45:27 +000073}
74
75SkImage* SkSurface_Gpu::onNewImageShapshot() {
robertphillips@google.com97b6b072012-10-31 14:48:39 +000076
77 GrRenderTarget* rt = (GrRenderTarget*) fDevice->accessRenderTarget();
78
79 return SkImage::NewTexture(rt->asTexture());
reed@google.com5d4ba882012-07-31 15:45:27 +000080}
81
82void SkSurface_Gpu::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y,
83 const SkPaint* paint) {
robertphillips@google.com97b6b072012-10-31 14:48:39 +000084 canvas->drawBitmap(fDevice->accessBitmap(false), x, y, paint);
85}
86
87// Copy the contents of the SkGpuDevice into a new texture and give that
88// texture to the SkImage. Note that this flushes the SkGpuDevice but
89// doesn't force an OpenGL flush.
90void SkSurface_Gpu::onCopyOnWrite(SkImage* image, SkCanvas* canvas) {
91 GrRenderTarget* rt = (GrRenderTarget*) fDevice->accessRenderTarget();
92
93 // are we sharing our render target with the image?
94 if (rt->asTexture() == SkTextureImageGetTexture(image)) {
95 GrTextureDesc desc;
96 // copyTexture requires a render target as the destination
97 desc.fFlags = kRenderTarget_GrTextureFlagBit;
98 desc.fWidth = fDevice->width();
99 desc.fHeight = fDevice->height();
100 desc.fConfig = SkBitmapConfig2GrPixelConfig(fDevice->config());
101 desc.fSampleCnt = 0;
102
robertphillips@google.com671eac62012-11-01 17:31:02 +0000103 SkAutoTUnref<GrTexture> tex(fDevice->context()->createUncachedTexture(desc, NULL, 0));
robertphillips@google.com97b6b072012-10-31 14:48:39 +0000104 if (NULL == tex) {
105 SkTextureImageSetTexture(image, NULL);
106 return;
107 }
skia.committer@gmail.comf3dc1992012-11-01 02:01:27 +0000108
robertphillips@google.com97b6b072012-10-31 14:48:39 +0000109 fDevice->context()->copyTexture(rt->asTexture(), tex->asRenderTarget());
110
111 SkTextureImageSetTexture(image, tex);
112 }
reed@google.com5d4ba882012-07-31 15:45:27 +0000113}
114
115///////////////////////////////////////////////////////////////////////////////
116
117SkSurface* SkSurface::NewRenderTargetDirect(GrContext* ctx,
118 GrRenderTarget* target) {
119 if (NULL == ctx || NULL == target) {
120 return NULL;
121 }
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000122
reed@google.com5d4ba882012-07-31 15:45:27 +0000123 return SkNEW_ARGS(SkSurface_Gpu, (ctx, target));
124}
125
126SkSurface* SkSurface::NewRenderTarget(GrContext* ctx, const SkImage::Info& info,
127 SkColorSpace*, int sampleCount) {
128 if (NULL == ctx) {
129 return NULL;
130 }
robertphillips@google.com97b6b072012-10-31 14:48:39 +0000131
132 bool isOpaque;
133 SkBitmap::Config config = SkImageInfoToBitmapConfig(info, &isOpaque);
134
135 GrTextureDesc desc;
136 desc.fFlags = kRenderTarget_GrTextureFlagBit;
137 desc.fWidth = info.fWidth;
138 desc.fHeight = info.fHeight;
139 desc.fConfig = SkBitmapConfig2GrPixelConfig(config);
140 desc.fSampleCnt = sampleCount;
141
robertphillips@google.com671eac62012-11-01 17:31:02 +0000142 SkAutoTUnref<GrTexture> tex(ctx->createUncachedTexture(desc, NULL, 0));
robertphillips@google.com97b6b072012-10-31 14:48:39 +0000143 if (NULL == tex) {
reed@google.com5d4ba882012-07-31 15:45:27 +0000144 return NULL;
145 }
skia.committer@gmail.comf3dc1992012-11-01 02:01:27 +0000146
robertphillips@google.com97b6b072012-10-31 14:48:39 +0000147 return SkNEW_ARGS(SkSurface_Gpu, (ctx, tex->asRenderTarget()));
reed@google.com5d4ba882012-07-31 15:45:27 +0000148}
149