blob: fa006a61cdb4f7acf421a7fae3467ae70c063e80 [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
bsalomonafe30052015-01-16 07:32:33 -08008#include "SkSurface_Gpu.h"
9
reed@google.com5d4ba882012-07-31 15:45:27 +000010#include "SkCanvas.h"
robertphillips@google.com97b6b072012-10-31 14:48:39 +000011#include "SkGpuDevice.h"
bsalomonafe30052015-01-16 07:32:33 -080012#include "SkImage_Base.h"
reed8b26b992015-05-07 15:36:17 -070013#include "SkImage_Gpu.h"
bsalomonafe30052015-01-16 07:32:33 -080014#include "SkImagePriv.h"
15#include "SkSurface_Base.h"
reed@google.com5d4ba882012-07-31 15:45:27 +000016
reedf037e0b2014-10-30 11:34:15 -070017#if SK_SUPPORT_GPU
18
reed@google.com5d4ba882012-07-31 15:45:27 +000019///////////////////////////////////////////////////////////////////////////////
bsalomonafe30052015-01-16 07:32:33 -080020SkSurface_Gpu::SkSurface_Gpu(SkGpuDevice* device)
21 : INHERITED(device->width(), device->height(), &device->surfaceProps())
22 , fDevice(SkRef(device)) {
robertphillips@google.com97b6b072012-10-31 14:48:39 +000023}
reed@google.com5d4ba882012-07-31 15:45:27 +000024
robertphillips@google.com97b6b072012-10-31 14:48:39 +000025SkSurface_Gpu::~SkSurface_Gpu() {
kkinnunenabcfab42015-02-22 22:53:44 -080026 fDevice->unref();
reed@google.com5d4ba882012-07-31 15:45:27 +000027}
28
29SkCanvas* SkSurface_Gpu::onNewCanvas() {
reed4a8126e2014-09-22 07:29:03 -070030 SkCanvas::InitFlags flags = SkCanvas::kDefault_InitFlags;
31 // When we think this works...
32// flags |= SkCanvas::kConservativeRasterClip_InitFlag;
33
robertphillipsfcf78292015-06-19 11:49:52 -070034 return SkNEW_ARGS(SkCanvas, (fDevice, flags));
reed@google.com5d4ba882012-07-31 15:45:27 +000035}
36
reed@google.com2bd8b812013-11-01 13:46:54 +000037SkSurface* SkSurface_Gpu::onNewSurface(const SkImageInfo& info) {
commit-bot@chromium.orgb8d00db2013-06-26 19:18:23 +000038 GrRenderTarget* rt = fDevice->accessRenderTarget();
vbuzinovdded6962015-06-12 08:59:45 -070039 int sampleCount = rt->numColorSamples();
bsalomonafe30052015-01-16 07:32:33 -080040 // TODO: Make caller specify this (change virtual signature of onNewSurface).
41 static const Budgeted kBudgeted = kNo_Budgeted;
42 return SkSurface::NewRenderTarget(fDevice->context(), kBudgeted, info, sampleCount,
43 &this->props());
reed@google.com5d4ba882012-07-31 15:45:27 +000044}
45
bsalomoneaaaf0b2015-01-23 08:08:04 -080046SkImage* SkSurface_Gpu::onNewImageSnapshot(Budgeted budgeted) {
reed8b26b992015-05-07 15:36:17 -070047 const SkImageInfo info = fDevice->imageInfo();
vbuzinovdded6962015-06-12 08:59:45 -070048 const int sampleCount = fDevice->accessRenderTarget()->numColorSamples();
reed8b26b992015-05-07 15:36:17 -070049 SkImage* image = NULL;
50 GrTexture* tex = fDevice->accessRenderTarget()->asTexture();
51 if (tex) {
52 image = SkNEW_ARGS(SkImage_Gpu,
53 (info.width(), info.height(), info.alphaType(),
54 tex, sampleCount, budgeted));
55 }
reed4af267b2014-11-21 08:46:37 -080056 if (image) {
57 as_IB(image)->initWithProps(this->props());
58 }
59 return image;
reed@google.com5d4ba882012-07-31 15:45:27 +000060}
61
kkinnunenabcfab42015-02-22 22:53:44 -080062// Create a new render target and, if necessary, copy the contents of the old
63// render target into it. Note that this flushes the SkGpuDevice but
robertphillips@google.com97b6b072012-10-31 14:48:39 +000064// doesn't force an OpenGL flush.
commit-bot@chromium.orgc4c98702013-04-22 14:28:01 +000065void SkSurface_Gpu::onCopyOnWrite(ContentChangeMode mode) {
commit-bot@chromium.orgb8d00db2013-06-26 19:18:23 +000066 GrRenderTarget* rt = fDevice->accessRenderTarget();
bsalomoneaaaf0b2015-01-23 08:08:04 -080067 // are we sharing our render target with the image? Note this call should never create a new
68 // image because onCopyOnWrite is only called when there is a cached image.
69 SkImage* image = this->getCachedImage(kNo_Budgeted);
70 SkASSERT(image);
bsalomon55812362015-06-10 08:49:28 -070071 if (rt->asTexture() == as_IB(image)->getTexture()) {
kkinnunenabcfab42015-02-22 22:53:44 -080072 this->fDevice->replaceRenderTarget(SkSurface::kRetain_ContentChangeMode == mode);
bsalomoneaaaf0b2015-01-23 08:08:04 -080073 SkTextureImageApplyBudgetedDecision(image);
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +000074 } else if (kDiscard_ContentChangeMode == mode) {
75 this->SkSurface_Gpu::onDiscard();
robertphillips@google.com97b6b072012-10-31 14:48:39 +000076 }
reed@google.com5d4ba882012-07-31 15:45:27 +000077}
78
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +000079void SkSurface_Gpu::onDiscard() {
80 fDevice->accessRenderTarget()->discard();
81}
82
reed@google.com5d4ba882012-07-31 15:45:27 +000083///////////////////////////////////////////////////////////////////////////////
84
reed4a8126e2014-09-22 07:29:03 -070085SkSurface* SkSurface::NewRenderTargetDirect(GrRenderTarget* target, const SkSurfaceProps* props) {
bsalomon74f681d2015-06-23 14:38:48 -070086 SkAutoTUnref<SkGpuDevice> device(
87 SkGpuDevice::Create(target, props, SkGpuDevice::kUninit_InitContents));
bsalomonafe30052015-01-16 07:32:33 -080088 if (!device) {
reed@google.com5d4ba882012-07-31 15:45:27 +000089 return NULL;
90 }
bsalomonafe30052015-01-16 07:32:33 -080091 return SkNEW_ARGS(SkSurface_Gpu, (device));
reed@google.com5d4ba882012-07-31 15:45:27 +000092}
93
bsalomonafe30052015-01-16 07:32:33 -080094SkSurface* SkSurface::NewRenderTarget(GrContext* ctx, Budgeted budgeted, const SkImageInfo& info,
95 int sampleCount, const SkSurfaceProps* props) {
96 SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(ctx, budgeted, info, sampleCount, props,
bsalomon74f681d2015-06-23 14:38:48 -070097 SkGpuDevice::kClear_InitContents));
bsalomonafe30052015-01-16 07:32:33 -080098 if (!device) {
reed@google.com5d4ba882012-07-31 15:45:27 +000099 return NULL;
100 }
bsalomonafe30052015-01-16 07:32:33 -0800101 return SkNEW_ARGS(SkSurface_Gpu, (device));
reed@google.com5d4ba882012-07-31 15:45:27 +0000102}
reedf037e0b2014-10-30 11:34:15 -0700103
bsalomone4579ad2015-04-08 08:38:40 -0700104SkSurface* SkSurface::NewWrappedRenderTarget(GrContext* context, GrBackendTextureDesc desc,
105 const SkSurfaceProps* props) {
106 if (NULL == context) {
107 return NULL;
108 }
109 if (!SkToBool(desc.fFlags & kRenderTarget_GrBackendTextureFlag)) {
110 return NULL;
111 }
bsalomon6dc6f5f2015-06-18 09:12:16 -0700112 SkAutoTUnref<GrSurface> surface(context->textureProvider()->wrapBackendTexture(desc,
113 kBorrow_GrWrapOwnership));
bsalomone4579ad2015-04-08 08:38:40 -0700114 if (!surface) {
115 return NULL;
116 }
bsalomon74f681d2015-06-23 14:38:48 -0700117 SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(surface->asRenderTarget(), props,
118 SkGpuDevice::kUninit_InitContents));
bsalomone4579ad2015-04-08 08:38:40 -0700119 if (!device) {
120 return NULL;
121 }
122 return SkNEW_ARGS(SkSurface_Gpu, (device));
123}
124
reedf037e0b2014-10-30 11:34:15 -0700125#endif