15d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com/* 25d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com * Copyright 2012 Google Inc. 35d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com * 45d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com * Use of this source code is governed by a BSD-style license that can be 55d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com * found in the LICENSE file. 65d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com */ 75d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com 8afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon#include "SkSurface_Gpu.h" 9afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon 105d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com#include "SkCanvas.h" 1197b6b0730dcb0feee9224ff04eb3985ca4bd0216robertphillips@google.com#include "SkGpuDevice.h" 12afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon#include "SkImage_Base.h" 138b26b99c97473f020df4b9d4ba789e074e06ceddreed#include "SkImage_Gpu.h" 14afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon#include "SkImagePriv.h" 15afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon#include "SkSurface_Base.h" 165d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com 17f037e0bf138a4e842f39e19864d05010a54950c9reed#if SK_SUPPORT_GPU 18f037e0bf138a4e842f39e19864d05010a54950c9reed 1997b6b0730dcb0feee9224ff04eb3985ca4bd0216robertphillips@google.com/////////////////////////////////////////////////////////////////////////////// 205d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com 21afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomonSkSurface_Gpu::SkSurface_Gpu(SkGpuDevice* device) 22afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon : INHERITED(device->width(), device->height(), &device->surfaceProps()) 23afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon , fDevice(SkRef(device)) { 2497b6b0730dcb0feee9224ff04eb3985ca4bd0216robertphillips@google.com} 255d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com 2697b6b0730dcb0feee9224ff04eb3985ca4bd0216robertphillips@google.comSkSurface_Gpu::~SkSurface_Gpu() { 27abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen fDevice->unref(); 285d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com} 295d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com 305d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.comSkCanvas* SkSurface_Gpu::onNewCanvas() { 314a8126e7f81384526629b1e21bf89b632ea13cd9reed SkCanvas::InitFlags flags = SkCanvas::kDefault_InitFlags; 324a8126e7f81384526629b1e21bf89b632ea13cd9reed // When we think this works... 334a8126e7f81384526629b1e21bf89b632ea13cd9reed// flags |= SkCanvas::kConservativeRasterClip_InitFlag; 344a8126e7f81384526629b1e21bf89b632ea13cd9reed 354a8126e7f81384526629b1e21bf89b632ea13cd9reed return SkNEW_ARGS(SkCanvas, (fDevice, &this->props(), flags)); 365d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com} 375d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com 382bd8b8100529c96c81c30f749f672f4caf775b04reed@google.comSkSurface* SkSurface_Gpu::onNewSurface(const SkImageInfo& info) { 39b8d00db075b5ea09e353508a26ef5ced50722a6ccommit-bot@chromium.org GrRenderTarget* rt = fDevice->accessRenderTarget(); 4097b6b0730dcb0feee9224ff04eb3985ca4bd0216robertphillips@google.com int sampleCount = rt->numSamples(); 41afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon // TODO: Make caller specify this (change virtual signature of onNewSurface). 42afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon static const Budgeted kBudgeted = kNo_Budgeted; 43afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon return SkSurface::NewRenderTarget(fDevice->context(), kBudgeted, info, sampleCount, 44afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon &this->props()); 455d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com} 465d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com 47eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomonSkImage* SkSurface_Gpu::onNewImageSnapshot(Budgeted budgeted) { 488b26b99c97473f020df4b9d4ba789e074e06ceddreed const SkImageInfo info = fDevice->imageInfo(); 494af267b11964d4a8acdb232ac46094c84d890e88reed const int sampleCount = fDevice->accessRenderTarget()->numSamples(); 508b26b99c97473f020df4b9d4ba789e074e06ceddreed SkImage* image = NULL; 518b26b99c97473f020df4b9d4ba789e074e06ceddreed GrTexture* tex = fDevice->accessRenderTarget()->asTexture(); 528b26b99c97473f020df4b9d4ba789e074e06ceddreed if (tex) { 538b26b99c97473f020df4b9d4ba789e074e06ceddreed image = SkNEW_ARGS(SkImage_Gpu, 548b26b99c97473f020df4b9d4ba789e074e06ceddreed (info.width(), info.height(), info.alphaType(), 558b26b99c97473f020df4b9d4ba789e074e06ceddreed tex, sampleCount, budgeted)); 568b26b99c97473f020df4b9d4ba789e074e06ceddreed } 574af267b11964d4a8acdb232ac46094c84d890e88reed if (image) { 584af267b11964d4a8acdb232ac46094c84d890e88reed as_IB(image)->initWithProps(this->props()); 594af267b11964d4a8acdb232ac46094c84d890e88reed } 604af267b11964d4a8acdb232ac46094c84d890e88reed return image; 615d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com} 625d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com 635d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.comvoid SkSurface_Gpu::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, 645d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com const SkPaint* paint) { 6597b6b0730dcb0feee9224ff04eb3985ca4bd0216robertphillips@google.com canvas->drawBitmap(fDevice->accessBitmap(false), x, y, paint); 6697b6b0730dcb0feee9224ff04eb3985ca4bd0216robertphillips@google.com} 6797b6b0730dcb0feee9224ff04eb3985ca4bd0216robertphillips@google.com 68abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen// Create a new render target and, if necessary, copy the contents of the old 69abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen// render target into it. Note that this flushes the SkGpuDevice but 7097b6b0730dcb0feee9224ff04eb3985ca4bd0216robertphillips@google.com// doesn't force an OpenGL flush. 71c4c9870953037be94da00ac9db887d171f6e479ccommit-bot@chromium.orgvoid SkSurface_Gpu::onCopyOnWrite(ContentChangeMode mode) { 72b8d00db075b5ea09e353508a26ef5ced50722a6ccommit-bot@chromium.org GrRenderTarget* rt = fDevice->accessRenderTarget(); 73eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon // are we sharing our render target with the image? Note this call should never create a new 74eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon // image because onCopyOnWrite is only called when there is a cached image. 75eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon SkImage* image = this->getCachedImage(kNo_Budgeted); 76eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon SkASSERT(image); 778b26b99c97473f020df4b9d4ba789e074e06ceddreed if (rt->asTexture() == image->getTexture()) { 78abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen this->fDevice->replaceRenderTarget(SkSurface::kRetain_ContentChangeMode == mode); 79eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon SkTextureImageApplyBudgetedDecision(image); 8028361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org } else if (kDiscard_ContentChangeMode == mode) { 8128361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org this->SkSurface_Gpu::onDiscard(); 8297b6b0730dcb0feee9224ff04eb3985ca4bd0216robertphillips@google.com } 835d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com} 845d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com 8528361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.orgvoid SkSurface_Gpu::onDiscard() { 8628361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org fDevice->accessRenderTarget()->discard(); 8728361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org} 8828361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org 895d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com/////////////////////////////////////////////////////////////////////////////// 905d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com 914a8126e7f81384526629b1e21bf89b632ea13cd9reedSkSurface* SkSurface::NewRenderTargetDirect(GrRenderTarget* target, const SkSurfaceProps* props) { 92afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(target, props)); 93afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon if (!device) { 945d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com return NULL; 955d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com } 96afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon return SkNEW_ARGS(SkSurface_Gpu, (device)); 97372b7a4f565354d2101092c6bac6f9550ad506fdreed@google.com} 98fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 99afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomonSkSurface* SkSurface::NewRenderTarget(GrContext* ctx, Budgeted budgeted, const SkImageInfo& info, 100afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon int sampleCount, const SkSurfaceProps* props) { 101afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(ctx, budgeted, info, sampleCount, props, 102afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon SkGpuDevice::kNeedClear_Flag)); 103afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon if (!device) { 1045d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com return NULL; 1055d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com } 106afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon return SkNEW_ARGS(SkSurface_Gpu, (device)); 1075d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com} 108f037e0bf138a4e842f39e19864d05010a54950c9reed 109e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomonSkSurface* SkSurface::NewWrappedRenderTarget(GrContext* context, GrBackendTextureDesc desc, 110e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon const SkSurfaceProps* props) { 111e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon if (NULL == context) { 112e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon return NULL; 113e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon } 114e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon if (!SkToBool(desc.fFlags & kRenderTarget_GrBackendTextureFlag)) { 115e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon return NULL; 116e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon } 117d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon SkAutoTUnref<GrSurface> surface(context->textureProvider()->wrapBackendTexture(desc)); 118e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon if (!surface) { 119e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon return NULL; 120e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon } 121e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(surface->asRenderTarget(), props, 122e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon SkGpuDevice::kNeedClear_Flag)); 123e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon if (!device) { 124e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon return NULL; 125e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon } 126e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon return SkNEW_ARGS(SkSurface_Gpu, (device)); 127e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon} 128e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon 129f037e0bf138a4e842f39e19864d05010a54950c9reed#endif 130