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 21 SkSurface_Gpu::SkSurface_Gpu(SkGpuDevice* device) 22 : INHERITED(device->width(), device->height(), &device->surfaceProps()) 23 , fDevice(SkRef(device)) { 24 } 25 26 SkSurface_Gpu::~SkSurface_Gpu() { 27 fDevice->unref(); 28 } 29 30 SkCanvas* 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 38 SkSurface* 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 47 SkImage* 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 63 void 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. 71 void 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 85 void SkSurface_Gpu::onDiscard() { 86 fDevice->accessRenderTarget()->discard(); 87 } 88 89 /////////////////////////////////////////////////////////////////////////////// 90 91 SkSurface* 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 99 SkSurface* 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 109 SkSurface* 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