SkSurface_Gpu.cpp revision fbfcd5602128ec010c82cb733c9cdc0a3254f9f3
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 85d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com#include "SkSurface_Base.h" 95d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com#include "SkImagePriv.h" 105d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com#include "SkCanvas.h" 115d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com#include "SkMallocPixelRef.h" 125d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com 135d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.comstatic const size_t kIgnoreRowBytesValue = (size_t)~0; 145d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com 155d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.comclass SkSurface_Gpu : public SkSurface_Base { 165d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.compublic: 175d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com static bool Valid(const SkImage::Info&, SkColorSpace*, size_t rb = kIgnoreRowBytesValue); 185d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com 195d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com SkSurface_Gpu(const SkImage::Info&, SkColorSpace*, void*, size_t rb); 205d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com SkSurface_Gpu(const SkImage::Info&, SkColorSpace*, SkPixelRef*, size_t rb); 215d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com 225d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com virtual SkCanvas* onNewCanvas() SK_OVERRIDE; 235d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com virtual SkSurface* onNewSurface(const SkImage::Info&, SkColorSpace*) SK_OVERRIDE; 245d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com virtual SkImage* onNewImageShapshot() SK_OVERRIDE; 255d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com virtual void onDraw(SkCanvas*, SkScalar x, SkScalar y, 265d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com const SkPaint*) SK_OVERRIDE; 275d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com 285d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.comprivate: 295d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com SkBitmap fBitmap; 305d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com bool fWeOwnThePixels; 315d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com 325d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com typedef SkSurface_Base INHERITED; 335d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com}; 345d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com 355d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com/////////////////////////////////////////////////////////////////////////////// 365d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com 375d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.combool SkSurface_Gpu::Valid(const SkImage::Info& info, SkColorSpace* cs, 385d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com size_t rowBytes) { 395d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com static const size_t kMaxTotalSize = SK_MaxS32; 405d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com 415d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com bool isOpaque; 425d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com SkBitmap::Config config = SkImageInfoToBitmapConfig(info, &isOpaque); 435d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com 445d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com int shift = 0; 455d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com switch (config) { 465d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com case SkBitmap::kA8_Config: 475d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com shift = 0; 485d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com break; 495d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com case SkBitmap::kRGB_565_Config: 505d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com shift = 1; 515d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com break; 525d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com case SkBitmap::kARGB_8888_Config: 535d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com shift = 2; 545d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com break; 555d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com default: 565d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com return false; 575d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com } 585d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com 595d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com // TODO: examine colorspace 605d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com 615d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com if (kIgnoreRowBytesValue == rowBytes) { 625d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com return true; 635d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com } 645d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com 655d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com uint64_t minRB = (uint64_t)info.fWidth << shift; 665d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com if (minRB > rowBytes) { 675d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com return false; 685d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com } 695d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com 705d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com size_t alignedRowBytes = rowBytes >> shift << shift; 715d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com if (alignedRowBytes != rowBytes) { 725d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com return false; 735d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com } 745d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com 755d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com uint64_t size = (uint64_t)info.fHeight * rowBytes; 765d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com if (size > kMaxTotalSize) { 775d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com return false; 785d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com } 79fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 805d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com return true; 815d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com} 825d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com 835d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.comSkSurface_Gpu::SkSurface_Gpu(const SkImage::Info& info, SkColorSpace* cs, 845d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com void* pixels, size_t rb) 855d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com : INHERITED(info.fWidth, info.fHeight) { 865d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com bool isOpaque; 875d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com SkBitmap::Config config = SkImageInfoToBitmapConfig(info, &isOpaque); 88fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 895d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com fBitmap.setConfig(config, info.fWidth, info.fHeight, rb); 905d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com fBitmap.setPixels(pixels); 915d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com fBitmap.setIsOpaque(isOpaque); 925d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com fWeOwnThePixels = false; 935d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com} 945d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com 955d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.comSkSurface_Gpu::SkSurface_Gpu(const SkImage::Info& info, SkColorSpace* cs, 965d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com SkPixelRef* pr, size_t rb) 975d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com : INHERITED(info.fWidth, info.fHeight) { 985d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com bool isOpaque; 995d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com SkBitmap::Config config = SkImageInfoToBitmapConfig(info, &isOpaque); 1005d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com 1015d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com fBitmap.setConfig(config, info.fWidth, info.fHeight, rb); 1025d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com fBitmap.setPixelRef(pr); 1035d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com fBitmap.setIsOpaque(isOpaque); 1045d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com fWeOwnThePixels = true; 1055d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com 1065d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com if (!isOpaque) { 1075d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com fBitmap.eraseColor(0); 1085d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com } 1095d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com} 1105d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com 1115d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.comSkCanvas* SkSurface_Gpu::onNewCanvas() { 1125d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com return SkNEW_ARGS(SkCanvas, (fBitmap)); 1135d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com} 1145d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com 1155d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.comSkSurface* SkSurface_Gpu::onNewSurface(const SkImage::Info& info, 1165d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com SkColorSpace* cs) { 1175d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com return SkSurface::NewRaster(info, cs); 1185d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com} 1195d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com 1205d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.comSkImage* SkSurface_Gpu::onNewImageShapshot() { 1215d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com // if we don't own the pixels, we need to make a deep-copy 1225d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com // if we do, we need to perform a copy-on-write the next time 1235d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com // we draw to this bitmap from our canvas... 1245d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com return SkNewImageFromBitmap(fBitmap); 1255d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com} 1265d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com 1275d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.comvoid SkSurface_Gpu::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, 1285d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com const SkPaint* paint) { 1295d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com canvas->drawBitmap(fBitmap, x, y, paint); 1305d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com} 1315d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com 1325d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com/////////////////////////////////////////////////////////////////////////////// 1335d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com 1345d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.comSkSurface* SkSurface::NewRenderTargetDirect(GrContext* ctx, 1355d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com GrRenderTarget* target) { 1365d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com if (NULL == ctx || NULL == target) { 1375d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com return NULL; 1385d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com } 139fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1405d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com return SkNEW_ARGS(SkSurface_Gpu, (ctx, target)); 1415d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com} 1425d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com 1435d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.comSkSurface* SkSurface::NewRenderTarget(GrContext* ctx, const SkImage::Info& info, 1445d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com SkColorSpace*, int sampleCount) { 1455d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com if (NULL == ctx) { 1465d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com return NULL; 1475d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com } 1485d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com if (!SkSurface_Gpu::Valid(info, cs, sampleCount)) { 1495d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com return NULL; 1505d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com } 151fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1525d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com// return SkNEW_ARGS(SkSurface_Gpu, (info, cs, pr, rowBytes)); 1535d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com} 1545d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com 155