blob: b94e4e30bd07f7a097a94a151a06b9558329476b [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"
13#include "SkImagePriv.h"
14#include "SkSurface_Base.h"
reed@google.com5d4ba882012-07-31 15:45:27 +000015
reedf037e0b2014-10-30 11:34:15 -070016#if SK_SUPPORT_GPU
17
reed@google.com5d4ba882012-07-31 15:45:27 +000018///////////////////////////////////////////////////////////////////////////////
19
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
34 return SkNEW_ARGS(SkCanvas, (fDevice, &this->props(), 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();
robertphillips@google.com97b6b072012-10-31 14:48:39 +000039 int sampleCount = rt->numSamples();
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) {
reed4af267b2014-11-21 08:46:37 -080047 const int sampleCount = fDevice->accessRenderTarget()->numSamples();
bsalomoneaaaf0b2015-01-23 08:08:04 -080048 SkImage* image = SkNewImageFromBitmapTexture(fDevice->accessBitmap(false), sampleCount,
49 budgeted);
reed4af267b2014-11-21 08:46:37 -080050 if (image) {
51 as_IB(image)->initWithProps(this->props());
52 }
53 return image;
reed@google.com5d4ba882012-07-31 15:45:27 +000054}
55
56void SkSurface_Gpu::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y,
57 const SkPaint* paint) {
robertphillips@google.com97b6b072012-10-31 14:48:39 +000058 canvas->drawBitmap(fDevice->accessBitmap(false), x, y, paint);
59}
60
kkinnunenabcfab42015-02-22 22:53:44 -080061// Create a new render target and, if necessary, copy the contents of the old
62// render target into it. Note that this flushes the SkGpuDevice but
robertphillips@google.com97b6b072012-10-31 14:48:39 +000063// doesn't force an OpenGL flush.
commit-bot@chromium.orgc4c98702013-04-22 14:28:01 +000064void SkSurface_Gpu::onCopyOnWrite(ContentChangeMode mode) {
commit-bot@chromium.orgb8d00db2013-06-26 19:18:23 +000065 GrRenderTarget* rt = fDevice->accessRenderTarget();
bsalomoneaaaf0b2015-01-23 08:08:04 -080066 // are we sharing our render target with the image? Note this call should never create a new
67 // image because onCopyOnWrite is only called when there is a cached image.
68 SkImage* image = this->getCachedImage(kNo_Budgeted);
69 SkASSERT(image);
70 if (rt->asTexture() == SkTextureImageGetTexture(image)) {
kkinnunenabcfab42015-02-22 22:53:44 -080071 this->fDevice->replaceRenderTarget(SkSurface::kRetain_ContentChangeMode == mode);
bsalomoneaaaf0b2015-01-23 08:08:04 -080072 SkTextureImageApplyBudgetedDecision(image);
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +000073 } else if (kDiscard_ContentChangeMode == mode) {
74 this->SkSurface_Gpu::onDiscard();
robertphillips@google.com97b6b072012-10-31 14:48:39 +000075 }
reed@google.com5d4ba882012-07-31 15:45:27 +000076}
77
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +000078void SkSurface_Gpu::onDiscard() {
79 fDevice->accessRenderTarget()->discard();
80}
81
reed@google.com5d4ba882012-07-31 15:45:27 +000082///////////////////////////////////////////////////////////////////////////////
83
reed4a8126e2014-09-22 07:29:03 -070084SkSurface* SkSurface::NewRenderTargetDirect(GrRenderTarget* target, const SkSurfaceProps* props) {
bsalomonafe30052015-01-16 07:32:33 -080085 SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(target, props));
86 if (!device) {
reed@google.com5d4ba882012-07-31 15:45:27 +000087 return NULL;
88 }
bsalomonafe30052015-01-16 07:32:33 -080089 return SkNEW_ARGS(SkSurface_Gpu, (device));
reed@google.com5d4ba882012-07-31 15:45:27 +000090}
91
bsalomonafe30052015-01-16 07:32:33 -080092SkSurface* SkSurface::NewRenderTarget(GrContext* ctx, Budgeted budgeted, const SkImageInfo& info,
93 int sampleCount, const SkSurfaceProps* props) {
94 SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(ctx, budgeted, info, sampleCount, props,
95 SkGpuDevice::kNeedClear_Flag));
96 if (!device) {
reed@google.com5d4ba882012-07-31 15:45:27 +000097 return NULL;
98 }
bsalomonafe30052015-01-16 07:32:33 -080099 return SkNEW_ARGS(SkSurface_Gpu, (device));
reed@google.com5d4ba882012-07-31 15:45:27 +0000100}
reedf037e0b2014-10-30 11:34:15 -0700101
102#endif