1/* 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 8#include "SkSurface_Gpu.h" 9 10#include "SkCanvas.h" 11#include "SkGpuDevice.h" 12#include "SkImage_Base.h" 13#include "SkImage_Gpu.h" 14#include "SkImagePriv.h" 15#include "SkSurface_Base.h" 16 17#if SK_SUPPORT_GPU 18 19/////////////////////////////////////////////////////////////////////////////// 20 21SkSurface_Gpu::SkSurface_Gpu(SkGpuDevice* device) 22 : INHERITED(device->width(), device->height(), &device->surfaceProps()) 23 , fDevice(SkRef(device)) { 24} 25 26SkSurface_Gpu::~SkSurface_Gpu() { 27 fDevice->unref(); 28} 29 30SkCanvas* SkSurface_Gpu::onNewCanvas() { 31 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)); 36} 37 38SkSurface* SkSurface_Gpu::onNewSurface(const SkImageInfo& info) { 39 GrRenderTarget* rt = fDevice->accessRenderTarget(); 40 int sampleCount = rt->numSamples(); 41 // 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()); 45} 46 47SkImage* SkSurface_Gpu::onNewImageSnapshot(Budgeted budgeted) { 48 const SkImageInfo info = fDevice->imageInfo(); 49 const int sampleCount = fDevice->accessRenderTarget()->numSamples(); 50 SkImage* image = NULL; 51 GrTexture* tex = fDevice->accessRenderTarget()->asTexture(); 52 if (tex) { 53 image = SkNEW_ARGS(SkImage_Gpu, 54 (info.width(), info.height(), info.alphaType(), 55 tex, sampleCount, budgeted)); 56 } 57 if (image) { 58 as_IB(image)->initWithProps(this->props()); 59 } 60 return image; 61} 62 63void SkSurface_Gpu::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, 64 const SkPaint* paint) { 65 canvas->drawBitmap(fDevice->accessBitmap(false), x, y, paint); 66} 67 68// Create a new render target and, if necessary, copy the contents of the old 69// render target into it. Note that this flushes the SkGpuDevice but 70// doesn't force an OpenGL flush. 71void SkSurface_Gpu::onCopyOnWrite(ContentChangeMode mode) { 72 GrRenderTarget* rt = fDevice->accessRenderTarget(); 73 // are we sharing our render target with the image? Note this call should never create a new 74 // image because onCopyOnWrite is only called when there is a cached image. 75 SkImage* image = this->getCachedImage(kNo_Budgeted); 76 SkASSERT(image); 77 if (rt->asTexture() == image->getTexture()) { 78 this->fDevice->replaceRenderTarget(SkSurface::kRetain_ContentChangeMode == mode); 79 SkTextureImageApplyBudgetedDecision(image); 80 } else if (kDiscard_ContentChangeMode == mode) { 81 this->SkSurface_Gpu::onDiscard(); 82 } 83} 84 85void SkSurface_Gpu::onDiscard() { 86 fDevice->accessRenderTarget()->discard(); 87} 88 89/////////////////////////////////////////////////////////////////////////////// 90 91SkSurface* SkSurface::NewRenderTargetDirect(GrRenderTarget* target, const SkSurfaceProps* props) { 92 SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(target, props)); 93 if (!device) { 94 return NULL; 95 } 96 return SkNEW_ARGS(SkSurface_Gpu, (device)); 97} 98 99SkSurface* SkSurface::NewRenderTarget(GrContext* ctx, Budgeted budgeted, const SkImageInfo& info, 100 int sampleCount, const SkSurfaceProps* props) { 101 SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(ctx, budgeted, info, sampleCount, props, 102 SkGpuDevice::kNeedClear_Flag)); 103 if (!device) { 104 return NULL; 105 } 106 return SkNEW_ARGS(SkSurface_Gpu, (device)); 107} 108 109SkSurface* SkSurface::NewWrappedRenderTarget(GrContext* context, GrBackendTextureDesc desc, 110 const SkSurfaceProps* props) { 111 if (NULL == context) { 112 return NULL; 113 } 114 if (!SkToBool(desc.fFlags & kRenderTarget_GrBackendTextureFlag)) { 115 return NULL; 116 } 117 SkAutoTUnref<GrSurface> surface(context->textureProvider()->wrapBackendTexture(desc)); 118 if (!surface) { 119 return NULL; 120 } 121 SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(surface->asRenderTarget(), props, 122 SkGpuDevice::kNeedClear_Flag)); 123 if (!device) { 124 return NULL; 125 } 126 return SkNEW_ARGS(SkSurface_Gpu, (device)); 127} 128 129#endif 130