blob: a1c31f31379ad022735e69dd5a64636f6149fca4 [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
bsalomon3582d3e2015-02-13 14:20:05 -080010#include "GrGpuResourcePriv.h"
reed@google.com5d4ba882012-07-31 15:45:27 +000011#include "SkCanvas.h"
robertphillips@google.com97b6b072012-10-31 14:48:39 +000012#include "SkGpuDevice.h"
bsalomonafe30052015-01-16 07:32:33 -080013#include "SkImage_Base.h"
14#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///////////////////////////////////////////////////////////////////////////////
20
bsalomonafe30052015-01-16 07:32:33 -080021SkSurface_Gpu::SkSurface_Gpu(SkGpuDevice* device)
22 : INHERITED(device->width(), device->height(), &device->surfaceProps())
23 , fDevice(SkRef(device)) {
robertphillips@google.com97b6b072012-10-31 14:48:39 +000024}
reed@google.com5d4ba882012-07-31 15:45:27 +000025
robertphillips@google.com97b6b072012-10-31 14:48:39 +000026SkSurface_Gpu::~SkSurface_Gpu() {
27 SkSafeUnref(fDevice);
reed@google.com5d4ba882012-07-31 15:45:27 +000028}
29
30SkCanvas* SkSurface_Gpu::onNewCanvas() {
reed4a8126e2014-09-22 07:29:03 -070031 SkCanvas::InitFlags flags = SkCanvas::kDefault_InitFlags;
32 // When we think this works...
33// flags |= SkCanvas::kConservativeRasterClip_InitFlag;
34
35 return SkNEW_ARGS(SkCanvas, (fDevice, &this->props(), flags));
reed@google.com5d4ba882012-07-31 15:45:27 +000036}
37
reed@google.com2bd8b812013-11-01 13:46:54 +000038SkSurface* SkSurface_Gpu::onNewSurface(const SkImageInfo& info) {
commit-bot@chromium.orgb8d00db2013-06-26 19:18:23 +000039 GrRenderTarget* rt = fDevice->accessRenderTarget();
robertphillips@google.com97b6b072012-10-31 14:48:39 +000040 int sampleCount = rt->numSamples();
bsalomonafe30052015-01-16 07:32:33 -080041 // TODO: Make caller specify this (change virtual signature of onNewSurface).
42 static const Budgeted kBudgeted = kNo_Budgeted;
43 return SkSurface::NewRenderTarget(fDevice->context(), kBudgeted, info, sampleCount,
44 &this->props());
reed@google.com5d4ba882012-07-31 15:45:27 +000045}
46
bsalomoneaaaf0b2015-01-23 08:08:04 -080047SkImage* SkSurface_Gpu::onNewImageSnapshot(Budgeted budgeted) {
reed4af267b2014-11-21 08:46:37 -080048 const int sampleCount = fDevice->accessRenderTarget()->numSamples();
bsalomoneaaaf0b2015-01-23 08:08:04 -080049 SkImage* image = SkNewImageFromBitmapTexture(fDevice->accessBitmap(false), sampleCount,
50 budgeted);
reed4af267b2014-11-21 08:46:37 -080051 if (image) {
52 as_IB(image)->initWithProps(this->props());
53 }
54 return image;
reed@google.com5d4ba882012-07-31 15:45:27 +000055}
56
57void SkSurface_Gpu::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y,
58 const SkPaint* paint) {
robertphillips@google.com97b6b072012-10-31 14:48:39 +000059 canvas->drawBitmap(fDevice->accessBitmap(false), x, y, paint);
60}
61
junov@chromium.org45c3db82013-04-11 17:52:05 +000062// Create a new SkGpuDevice and, if necessary, copy the contents of the old
63// device 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);
71 if (rt->asTexture() == SkTextureImageGetTexture(image)) {
bsalomonafe30052015-01-16 07:32:33 -080072 GrRenderTarget* oldRT = this->fDevice->accessRenderTarget();
bsalomon3582d3e2015-02-13 14:20:05 -080073 SkSurface::Budgeted budgeted = oldRT->resourcePriv().isBudgeted() ? kYes_Budgeted :
74 kNo_Budgeted;
bsalomonafe30052015-01-16 07:32:33 -080075 SkAutoTUnref<SkGpuDevice> newDevice(
76 SkGpuDevice::Create(oldRT->getContext(), budgeted, fDevice->imageInfo(),
77 oldRT->numSamples(), &this->props(), 0));
78 if (kRetain_ContentChangeMode == mode && !oldRT->wasDestroyed() && newDevice) {
79 oldRT->getContext()->copySurface(newDevice->accessRenderTarget(), oldRT);
commit-bot@chromium.orgc4c98702013-04-22 14:28:01 +000080 }
bsalomonafe30052015-01-16 07:32:33 -080081
bsalomon49f085d2014-09-05 13:34:00 -070082 SkASSERT(this->getCachedCanvas());
junov@chromium.orgacea3ef2013-04-16 19:41:09 +000083 SkASSERT(this->getCachedCanvas()->getDevice() == fDevice);
commit-bot@chromium.orge492ac42014-03-04 22:37:29 +000084
commit-bot@chromium.org403f8d72014-02-17 15:24:26 +000085 this->getCachedCanvas()->setRootDevice(newDevice);
bsalomonafe30052015-01-16 07:32:33 -080086 SkRefCnt_SafeAssign(fDevice, newDevice.get());
87
bsalomoneaaaf0b2015-01-23 08:08:04 -080088 SkTextureImageApplyBudgetedDecision(image);
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +000089 } else if (kDiscard_ContentChangeMode == mode) {
90 this->SkSurface_Gpu::onDiscard();
robertphillips@google.com97b6b072012-10-31 14:48:39 +000091 }
reed@google.com5d4ba882012-07-31 15:45:27 +000092}
93
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +000094void SkSurface_Gpu::onDiscard() {
95 fDevice->accessRenderTarget()->discard();
96}
97
reed@google.com5d4ba882012-07-31 15:45:27 +000098///////////////////////////////////////////////////////////////////////////////
99
reed4a8126e2014-09-22 07:29:03 -0700100SkSurface* SkSurface::NewRenderTargetDirect(GrRenderTarget* target, const SkSurfaceProps* props) {
bsalomonafe30052015-01-16 07:32:33 -0800101 SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(target, props));
102 if (!device) {
reed@google.com5d4ba882012-07-31 15:45:27 +0000103 return NULL;
104 }
bsalomonafe30052015-01-16 07:32:33 -0800105 return SkNEW_ARGS(SkSurface_Gpu, (device));
reed@google.com5d4ba882012-07-31 15:45:27 +0000106}
107
bsalomonafe30052015-01-16 07:32:33 -0800108SkSurface* SkSurface::NewRenderTarget(GrContext* ctx, Budgeted budgeted, const SkImageInfo& info,
109 int sampleCount, const SkSurfaceProps* props) {
110 SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(ctx, budgeted, info, sampleCount, props,
111 SkGpuDevice::kNeedClear_Flag));
112 if (!device) {
reed@google.com5d4ba882012-07-31 15:45:27 +0000113 return NULL;
114 }
bsalomonafe30052015-01-16 07:32:33 -0800115 return SkNEW_ARGS(SkSurface_Gpu, (device));
reed@google.com5d4ba882012-07-31 15:45:27 +0000116}
reedf037e0b2014-10-30 11:34:15 -0700117
118#endif