blob: 2d5645b2b016d734b2c170881b8e7b276182d6ba [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
bsalomonafe30052015-01-16 07:32:33 -080019SkSurface_Gpu::SkSurface_Gpu(SkGpuDevice* device)
20 : INHERITED(device->width(), device->height(), &device->surfaceProps())
21 , fDevice(SkRef(device)) {
robertphillips@google.com97b6b072012-10-31 14:48:39 +000022}
reed@google.com5d4ba882012-07-31 15:45:27 +000023
robertphillips@google.com97b6b072012-10-31 14:48:39 +000024SkSurface_Gpu::~SkSurface_Gpu() {
kkinnunenabcfab42015-02-22 22:53:44 -080025 fDevice->unref();
reed@google.com5d4ba882012-07-31 15:45:27 +000026}
27
joshualitt81793412015-07-08 12:54:04 -070028static GrRenderTarget* prepare_rt_for_external_access(SkSurface_Gpu* surface,
29 SkSurface::BackendHandleAccess access) {
reedfa5e68e2015-06-29 07:37:01 -070030 switch (access) {
joshualitt81793412015-07-08 12:54:04 -070031 case SkSurface::kFlushRead_BackendHandleAccess:
reedfa5e68e2015-06-29 07:37:01 -070032 break;
joshualitt81793412015-07-08 12:54:04 -070033 case SkSurface::kFlushWrite_BackendHandleAccess:
34 case SkSurface::kDiscardWrite_BackendHandleAccess:
reed884200e2015-06-29 09:00:20 -070035 // for now we don't special-case on Discard, but we may in the future.
joshualitt81793412015-07-08 12:54:04 -070036 surface->notifyContentWillChange(SkSurface::kRetain_ContentChangeMode);
reeddca20ce2015-07-03 10:43:43 -070037 // legacy: need to dirty the bitmap's genID in our device (curse it)
joshualitt81793412015-07-08 12:54:04 -070038 surface->getDevice()->accessBitmap(false).notifyPixelsChanged();
reedfa5e68e2015-06-29 07:37:01 -070039 break;
reedfa5e68e2015-06-29 07:37:01 -070040 }
fmalitae2639082015-08-06 07:04:51 -070041
42 // Grab the render target *after* firing notifications, as it may get switched if CoW kicks in.
43 GrRenderTarget* rt = surface->getDevice()->accessRenderTarget();
bsalomonc49e8682015-06-30 11:37:35 -070044 rt->prepareForExternalIO();
joshualitt81793412015-07-08 12:54:04 -070045 return rt;
46}
47
48GrBackendObject SkSurface_Gpu::onGetTextureHandle(BackendHandleAccess access) {
49 GrRenderTarget* rt = prepare_rt_for_external_access(this, access);
50 GrTexture* texture = rt->asTexture();
51 if (texture) {
52 return texture->getTextureHandle();
53 }
54 return 0;
55}
56
57bool SkSurface_Gpu::onGetRenderTargetHandle(GrBackendObject* obj, BackendHandleAccess access) {
58 GrRenderTarget* rt = prepare_rt_for_external_access(this, access);
59 *obj = rt->getRenderTargetHandle();
60 return true;
reedfa5e68e2015-06-29 07:37:01 -070061}
62
reed@google.com5d4ba882012-07-31 15:45:27 +000063SkCanvas* SkSurface_Gpu::onNewCanvas() {
reed4a8126e2014-09-22 07:29:03 -070064 SkCanvas::InitFlags flags = SkCanvas::kDefault_InitFlags;
65 // When we think this works...
66// flags |= SkCanvas::kConservativeRasterClip_InitFlag;
67
halcanary385fe4d2015-08-26 13:07:48 -070068 return new SkCanvas(fDevice, flags);
reed@google.com5d4ba882012-07-31 15:45:27 +000069}
70
reed@google.com2bd8b812013-11-01 13:46:54 +000071SkSurface* SkSurface_Gpu::onNewSurface(const SkImageInfo& info) {
commit-bot@chromium.orgb8d00db2013-06-26 19:18:23 +000072 GrRenderTarget* rt = fDevice->accessRenderTarget();
vbuzinovdded6962015-06-12 08:59:45 -070073 int sampleCount = rt->numColorSamples();
bsalomonafe30052015-01-16 07:32:33 -080074 // TODO: Make caller specify this (change virtual signature of onNewSurface).
75 static const Budgeted kBudgeted = kNo_Budgeted;
76 return SkSurface::NewRenderTarget(fDevice->context(), kBudgeted, info, sampleCount,
77 &this->props());
reed@google.com5d4ba882012-07-31 15:45:27 +000078}
79
bsalomoneaaaf0b2015-01-23 08:08:04 -080080SkImage* SkSurface_Gpu::onNewImageSnapshot(Budgeted budgeted) {
reed8b26b992015-05-07 15:36:17 -070081 const SkImageInfo info = fDevice->imageInfo();
halcanary96fcdcc2015-08-27 07:41:13 -070082 SkImage* image = nullptr;
reed8b26b992015-05-07 15:36:17 -070083 GrTexture* tex = fDevice->accessRenderTarget()->asTexture();
84 if (tex) {
halcanary385fe4d2015-08-26 13:07:48 -070085 image = new SkImage_Gpu(info.width(), info.height(), kNeedNewImageUniqueID,
reed7b6945b2015-09-24 00:50:58 -070086 info.alphaType(), tex, budgeted);
reed8b26b992015-05-07 15:36:17 -070087 }
reed4af267b2014-11-21 08:46:37 -080088 return image;
reed@google.com5d4ba882012-07-31 15:45:27 +000089}
90
kkinnunenabcfab42015-02-22 22:53:44 -080091// Create a new render target and, if necessary, copy the contents of the old
92// render target into it. Note that this flushes the SkGpuDevice but
robertphillips@google.com97b6b072012-10-31 14:48:39 +000093// doesn't force an OpenGL flush.
commit-bot@chromium.orgc4c98702013-04-22 14:28:01 +000094void SkSurface_Gpu::onCopyOnWrite(ContentChangeMode mode) {
commit-bot@chromium.orgb8d00db2013-06-26 19:18:23 +000095 GrRenderTarget* rt = fDevice->accessRenderTarget();
bsalomoneaaaf0b2015-01-23 08:08:04 -080096 // are we sharing our render target with the image? Note this call should never create a new
97 // image because onCopyOnWrite is only called when there is a cached image.
98 SkImage* image = this->getCachedImage(kNo_Budgeted);
99 SkASSERT(image);
bsalomon55812362015-06-10 08:49:28 -0700100 if (rt->asTexture() == as_IB(image)->getTexture()) {
kkinnunenabcfab42015-02-22 22:53:44 -0800101 this->fDevice->replaceRenderTarget(SkSurface::kRetain_ContentChangeMode == mode);
bsalomoneaaaf0b2015-01-23 08:08:04 -0800102 SkTextureImageApplyBudgetedDecision(image);
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000103 } else if (kDiscard_ContentChangeMode == mode) {
104 this->SkSurface_Gpu::onDiscard();
robertphillips@google.com97b6b072012-10-31 14:48:39 +0000105 }
reed@google.com5d4ba882012-07-31 15:45:27 +0000106}
107
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000108void SkSurface_Gpu::onDiscard() {
109 fDevice->accessRenderTarget()->discard();
110}
111
reed@google.com5d4ba882012-07-31 15:45:27 +0000112///////////////////////////////////////////////////////////////////////////////
113
reed4a8126e2014-09-22 07:29:03 -0700114SkSurface* SkSurface::NewRenderTargetDirect(GrRenderTarget* target, const SkSurfaceProps* props) {
bsalomon74f681d2015-06-23 14:38:48 -0700115 SkAutoTUnref<SkGpuDevice> device(
116 SkGpuDevice::Create(target, props, SkGpuDevice::kUninit_InitContents));
bsalomonafe30052015-01-16 07:32:33 -0800117 if (!device) {
halcanary96fcdcc2015-08-27 07:41:13 -0700118 return nullptr;
reed@google.com5d4ba882012-07-31 15:45:27 +0000119 }
halcanary385fe4d2015-08-26 13:07:48 -0700120 return new SkSurface_Gpu(device);
reed@google.com5d4ba882012-07-31 15:45:27 +0000121}
122
bsalomonafe30052015-01-16 07:32:33 -0800123SkSurface* SkSurface::NewRenderTarget(GrContext* ctx, Budgeted budgeted, const SkImageInfo& info,
jcgregorioe7d7f902016-02-04 19:51:25 -0800124 int sampleCount, const SkSurfaceProps* props) {
125 SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(ctx, budgeted, info, sampleCount, props,
126 SkGpuDevice::kClear_InitContents));
bsalomonafe30052015-01-16 07:32:33 -0800127 if (!device) {
halcanary96fcdcc2015-08-27 07:41:13 -0700128 return nullptr;
reed@google.com5d4ba882012-07-31 15:45:27 +0000129 }
halcanary385fe4d2015-08-26 13:07:48 -0700130 return new SkSurface_Gpu(device);
reed@google.com5d4ba882012-07-31 15:45:27 +0000131}
reedf037e0b2014-10-30 11:34:15 -0700132
bsalomond3e259a2015-06-30 12:04:40 -0700133SkSurface* SkSurface::NewFromBackendTexture(GrContext* context, const GrBackendTextureDesc& desc,
134 const SkSurfaceProps* props) {
halcanary96fcdcc2015-08-27 07:41:13 -0700135 if (nullptr == context) {
136 return nullptr;
bsalomone4579ad2015-04-08 08:38:40 -0700137 }
138 if (!SkToBool(desc.fFlags & kRenderTarget_GrBackendTextureFlag)) {
halcanary96fcdcc2015-08-27 07:41:13 -0700139 return nullptr;
bsalomone4579ad2015-04-08 08:38:40 -0700140 }
bsalomon6dc6f5f2015-06-18 09:12:16 -0700141 SkAutoTUnref<GrSurface> surface(context->textureProvider()->wrapBackendTexture(desc,
142 kBorrow_GrWrapOwnership));
bsalomone4579ad2015-04-08 08:38:40 -0700143 if (!surface) {
halcanary96fcdcc2015-08-27 07:41:13 -0700144 return nullptr;
bsalomone4579ad2015-04-08 08:38:40 -0700145 }
bsalomon74f681d2015-06-23 14:38:48 -0700146 SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(surface->asRenderTarget(), props,
147 SkGpuDevice::kUninit_InitContents));
bsalomone4579ad2015-04-08 08:38:40 -0700148 if (!device) {
halcanary96fcdcc2015-08-27 07:41:13 -0700149 return nullptr;
bsalomone4579ad2015-04-08 08:38:40 -0700150 }
halcanary385fe4d2015-08-26 13:07:48 -0700151 return new SkSurface_Gpu(device);
bsalomone4579ad2015-04-08 08:38:40 -0700152}
153
bsalomond3e259a2015-06-30 12:04:40 -0700154SkSurface* SkSurface::NewFromBackendRenderTarget(GrContext* context,
155 const GrBackendRenderTargetDesc& desc,
156 const SkSurfaceProps* props) {
halcanary96fcdcc2015-08-27 07:41:13 -0700157 if (nullptr == context) {
158 return nullptr;
bsalomond3e259a2015-06-30 12:04:40 -0700159 }
160 SkAutoTUnref<GrRenderTarget> rt(context->textureProvider()->wrapBackendRenderTarget(desc));
161 if (!rt) {
halcanary96fcdcc2015-08-27 07:41:13 -0700162 return nullptr;
bsalomond3e259a2015-06-30 12:04:40 -0700163 }
164 SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(rt, props,
165 SkGpuDevice::kUninit_InitContents));
166 if (!device) {
halcanary96fcdcc2015-08-27 07:41:13 -0700167 return nullptr;
bsalomond3e259a2015-06-30 12:04:40 -0700168 }
halcanary385fe4d2015-08-26 13:07:48 -0700169 return new SkSurface_Gpu(device);
bsalomond3e259a2015-06-30 12:04:40 -0700170}
171
reedf037e0b2014-10-30 11:34:15 -0700172#endif