blob: 34031f23015acfb6f352e24b35034f527bb16b0d [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));
reed@google.com5d4ba882012-07-31 15:45:27 +000045}
46
robertphillips@google.com97b6b072012-10-31 14:48:39 +000047SkSurface_Gpu::SkSurface_Gpu(GrContext* ctx, GrRenderTarget* renderTarget)
48 : INHERITED(renderTarget->width(), renderTarget->height()) {
49 fDevice = SkNEW_ARGS(SkGpuDevice, (ctx, renderTarget));
50}
reed@google.com5d4ba882012-07-31 15:45:27 +000051
robertphillips@google.com97b6b072012-10-31 14:48:39 +000052SkSurface_Gpu::~SkSurface_Gpu() {
53 SkSafeUnref(fDevice);
reed@google.com5d4ba882012-07-31 15:45:27 +000054}
55
56SkCanvas* SkSurface_Gpu::onNewCanvas() {
robertphillips@google.com97b6b072012-10-31 14:48:39 +000057 return SkNEW_ARGS(SkCanvas, (fDevice));
reed@google.com5d4ba882012-07-31 15:45:27 +000058}
59
60SkSurface* SkSurface_Gpu::onNewSurface(const SkImage::Info& info,
robertphillips@google.com97b6b072012-10-31 14:48:39 +000061 SkColorSpace* cs) {
62 GrRenderTarget* rt = (GrRenderTarget*) fDevice->accessRenderTarget();
63 int sampleCount = rt->numSamples();
64 return SkSurface::NewRenderTarget(fDevice->context(), info, NULL, sampleCount);
reed@google.com5d4ba882012-07-31 15:45:27 +000065}
66
67SkImage* SkSurface_Gpu::onNewImageShapshot() {
robertphillips@google.com97b6b072012-10-31 14:48:39 +000068
69 GrRenderTarget* rt = (GrRenderTarget*) fDevice->accessRenderTarget();
70
71 return SkImage::NewTexture(rt->asTexture());
reed@google.com5d4ba882012-07-31 15:45:27 +000072}
73
74void SkSurface_Gpu::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y,
75 const SkPaint* paint) {
robertphillips@google.com97b6b072012-10-31 14:48:39 +000076 canvas->drawBitmap(fDevice->accessBitmap(false), x, y, paint);
77}
78
79// Copy the contents of the SkGpuDevice into a new texture and give that
80// texture to the SkImage. Note that this flushes the SkGpuDevice but
81// doesn't force an OpenGL flush.
82void SkSurface_Gpu::onCopyOnWrite(SkImage* image, SkCanvas* canvas) {
83 GrRenderTarget* rt = (GrRenderTarget*) fDevice->accessRenderTarget();
84
85 // are we sharing our render target with the image?
86 if (rt->asTexture() == SkTextureImageGetTexture(image)) {
87 GrTextureDesc desc;
88 // copyTexture requires a render target as the destination
89 desc.fFlags = kRenderTarget_GrTextureFlagBit;
90 desc.fWidth = fDevice->width();
91 desc.fHeight = fDevice->height();
92 desc.fConfig = SkBitmapConfig2GrPixelConfig(fDevice->config());
93 desc.fSampleCnt = 0;
94
robertphillips@google.com671eac62012-11-01 17:31:02 +000095 SkAutoTUnref<GrTexture> tex(fDevice->context()->createUncachedTexture(desc, NULL, 0));
robertphillips@google.com97b6b072012-10-31 14:48:39 +000096 if (NULL == tex) {
97 SkTextureImageSetTexture(image, NULL);
98 return;
99 }
skia.committer@gmail.comf3dc1992012-11-01 02:01:27 +0000100
robertphillips@google.com97b6b072012-10-31 14:48:39 +0000101 fDevice->context()->copyTexture(rt->asTexture(), tex->asRenderTarget());
102
103 SkTextureImageSetTexture(image, tex);
104 }
reed@google.com5d4ba882012-07-31 15:45:27 +0000105}
106
107///////////////////////////////////////////////////////////////////////////////
108
109SkSurface* SkSurface::NewRenderTargetDirect(GrContext* ctx,
110 GrRenderTarget* target) {
111 if (NULL == ctx || NULL == target) {
112 return NULL;
113 }
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000114
reed@google.com5d4ba882012-07-31 15:45:27 +0000115 return SkNEW_ARGS(SkSurface_Gpu, (ctx, target));
116}
117
118SkSurface* SkSurface::NewRenderTarget(GrContext* ctx, const SkImage::Info& info,
119 SkColorSpace*, int sampleCount) {
120 if (NULL == ctx) {
121 return NULL;
122 }
robertphillips@google.com97b6b072012-10-31 14:48:39 +0000123
124 bool isOpaque;
125 SkBitmap::Config config = SkImageInfoToBitmapConfig(info, &isOpaque);
126
127 GrTextureDesc desc;
128 desc.fFlags = kRenderTarget_GrTextureFlagBit;
129 desc.fWidth = info.fWidth;
130 desc.fHeight = info.fHeight;
131 desc.fConfig = SkBitmapConfig2GrPixelConfig(config);
132 desc.fSampleCnt = sampleCount;
133
robertphillips@google.com671eac62012-11-01 17:31:02 +0000134 SkAutoTUnref<GrTexture> tex(ctx->createUncachedTexture(desc, NULL, 0));
robertphillips@google.com97b6b072012-10-31 14:48:39 +0000135 if (NULL == tex) {
reed@google.com5d4ba882012-07-31 15:45:27 +0000136 return NULL;
137 }
skia.committer@gmail.comf3dc1992012-11-01 02:01:27 +0000138
robertphillips@google.com97b6b072012-10-31 14:48:39 +0000139 return SkNEW_ARGS(SkSurface_Gpu, (ctx, tex->asRenderTarget()));
reed@google.com5d4ba882012-07-31 15:45:27 +0000140}
141