1c9062047cea66575868270b4dcaeb1dab113c8a7reed@google.com/* 2c9062047cea66575868270b4dcaeb1dab113c8a7reed@google.com * Copyright 2012 Google Inc. 3c9062047cea66575868270b4dcaeb1dab113c8a7reed@google.com * 4c9062047cea66575868270b4dcaeb1dab113c8a7reed@google.com * Use of this source code is governed by a BSD-style license that can be 5c9062047cea66575868270b4dcaeb1dab113c8a7reed@google.com * found in the LICENSE file. 6c9062047cea66575868270b4dcaeb1dab113c8a7reed@google.com */ 7c9062047cea66575868270b4dcaeb1dab113c8a7reed@google.com 89ea5a3bc7361cb88d37280b5922fba9430fed328reed@google.com#include "SkSurface_Base.h" 9889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com#include "SkImagePriv.h" 10889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com#include "SkCanvas.h" 11889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com 124a8126e7f81384526629b1e21bf89b632ea13cd9reed#include "SkFontLCDConfig.h" 134a8126e7f81384526629b1e21bf89b632ea13cd9reedstatic SkPixelGeometry compute_default_geometry() { 144a8126e7f81384526629b1e21bf89b632ea13cd9reed SkFontLCDConfig::LCDOrder order = SkFontLCDConfig::GetSubpixelOrder(); 154a8126e7f81384526629b1e21bf89b632ea13cd9reed if (SkFontLCDConfig::kNONE_LCDOrder == order) { 164a8126e7f81384526629b1e21bf89b632ea13cd9reed return kUnknown_SkPixelGeometry; 174a8126e7f81384526629b1e21bf89b632ea13cd9reed } else { 184a8126e7f81384526629b1e21bf89b632ea13cd9reed // Bit0 is RGB(0), BGR(1) 194a8126e7f81384526629b1e21bf89b632ea13cd9reed // Bit1 is H(0), V(1) 204a8126e7f81384526629b1e21bf89b632ea13cd9reed const SkPixelGeometry gGeo[] = { 214a8126e7f81384526629b1e21bf89b632ea13cd9reed kRGB_H_SkPixelGeometry, 224a8126e7f81384526629b1e21bf89b632ea13cd9reed kBGR_H_SkPixelGeometry, 234a8126e7f81384526629b1e21bf89b632ea13cd9reed kRGB_V_SkPixelGeometry, 244a8126e7f81384526629b1e21bf89b632ea13cd9reed kBGR_V_SkPixelGeometry, 254a8126e7f81384526629b1e21bf89b632ea13cd9reed }; 264a8126e7f81384526629b1e21bf89b632ea13cd9reed int index = 0; 274a8126e7f81384526629b1e21bf89b632ea13cd9reed if (SkFontLCDConfig::kBGR_LCDOrder == order) { 284a8126e7f81384526629b1e21bf89b632ea13cd9reed index |= 1; 294a8126e7f81384526629b1e21bf89b632ea13cd9reed } 304a8126e7f81384526629b1e21bf89b632ea13cd9reed if (SkFontLCDConfig::kVertical_LCDOrientation == SkFontLCDConfig::GetSubpixelOrientation()){ 314a8126e7f81384526629b1e21bf89b632ea13cd9reed index |= 2; 324a8126e7f81384526629b1e21bf89b632ea13cd9reed } 334a8126e7f81384526629b1e21bf89b632ea13cd9reed return gGeo[index]; 344a8126e7f81384526629b1e21bf89b632ea13cd9reed } 354a8126e7f81384526629b1e21bf89b632ea13cd9reed} 364a8126e7f81384526629b1e21bf89b632ea13cd9reed 374a8126e7f81384526629b1e21bf89b632ea13cd9reedSkSurfaceProps::SkSurfaceProps() : fFlags(0), fPixelGeometry(kUnknown_SkPixelGeometry) {} 384a8126e7f81384526629b1e21bf89b632ea13cd9reed 394a8126e7f81384526629b1e21bf89b632ea13cd9reedSkSurfaceProps::SkSurfaceProps(InitType) : fFlags(0), fPixelGeometry(compute_default_geometry()) {} 404a8126e7f81384526629b1e21bf89b632ea13cd9reed 414a8126e7f81384526629b1e21bf89b632ea13cd9reedSkSurfaceProps::SkSurfaceProps(uint32_t flags, InitType) 424a8126e7f81384526629b1e21bf89b632ea13cd9reed : fFlags(flags) 434a8126e7f81384526629b1e21bf89b632ea13cd9reed , fPixelGeometry(compute_default_geometry()) 444a8126e7f81384526629b1e21bf89b632ea13cd9reed{} 454a8126e7f81384526629b1e21bf89b632ea13cd9reed 464a8126e7f81384526629b1e21bf89b632ea13cd9reedSkSurfaceProps::SkSurfaceProps(uint32_t flags, SkPixelGeometry pg) 474a8126e7f81384526629b1e21bf89b632ea13cd9reed : fFlags(flags), fPixelGeometry(pg) 484a8126e7f81384526629b1e21bf89b632ea13cd9reed{} 494a8126e7f81384526629b1e21bf89b632ea13cd9reed 504af267b11964d4a8acdb232ac46094c84d890e88reedSkSurfaceProps::SkSurfaceProps(const SkSurfaceProps& other) 514af267b11964d4a8acdb232ac46094c84d890e88reed : fFlags(other.fFlags) 524af267b11964d4a8acdb232ac46094c84d890e88reed , fPixelGeometry(other.fPixelGeometry) 534af267b11964d4a8acdb232ac46094c84d890e88reed{} 544af267b11964d4a8acdb232ac46094c84d890e88reed 55889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com/////////////////////////////////////////////////////////////////////////////// 56889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com 574a8126e7f81384526629b1e21bf89b632ea13cd9reedSkSurface_Base::SkSurface_Base(int width, int height, const SkSurfaceProps* props) 584a8126e7f81384526629b1e21bf89b632ea13cd9reed : INHERITED(width, height, props) 594a8126e7f81384526629b1e21bf89b632ea13cd9reed{ 609ea5a3bc7361cb88d37280b5922fba9430fed328reed@google.com fCachedCanvas = NULL; 6197af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com fCachedImage = NULL; 629ea5a3bc7361cb88d37280b5922fba9430fed328reed@google.com} 63889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com 644a8126e7f81384526629b1e21bf89b632ea13cd9reedSkSurface_Base::SkSurface_Base(const SkImageInfo& info, const SkSurfaceProps* props) 654a8126e7f81384526629b1e21bf89b632ea13cd9reed : INHERITED(info, props) 664a8126e7f81384526629b1e21bf89b632ea13cd9reed{ 671360c52b10dad45d7a6850370eab40c6253d7988reed@google.com fCachedCanvas = NULL; 681360c52b10dad45d7a6850370eab40c6253d7988reed@google.com fCachedImage = NULL; 691360c52b10dad45d7a6850370eab40c6253d7988reed@google.com} 701360c52b10dad45d7a6850370eab40c6253d7988reed@google.com 719ea5a3bc7361cb88d37280b5922fba9430fed328reed@google.comSkSurface_Base::~SkSurface_Base() { 7297af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com // in case the canvas outsurvives us, we null the callback 7397af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com if (fCachedCanvas) { 7497af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com fCachedCanvas->setSurfaceBase(NULL); 7597af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com } 7697af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com 7797af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com SkSafeUnref(fCachedImage); 789ea5a3bc7361cb88d37280b5922fba9430fed328reed@google.com SkSafeUnref(fCachedCanvas); 799ea5a3bc7361cb88d37280b5922fba9430fed328reed@google.com} 80889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com 814a8126e7f81384526629b1e21bf89b632ea13cd9reedvoid SkSurface_Base::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint) { 82eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon SkImage* image = this->newImageSnapshot(kYes_Budgeted); 83889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com if (image) { 84b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr canvas->drawImage(image, x, y, paint); 85889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com image->unref(); 86889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com } 87889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com} 88889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com 89c4c9870953037be94da00ac9db887d171f6e479ccommit-bot@chromium.orgvoid SkSurface_Base::aboutToDraw(ContentChangeMode mode) { 9097af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com this->dirtyGenerationID(); 9197af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com 9228361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org SkASSERT(!fCachedCanvas || fCachedCanvas->getSurfaceBase() == this); 9397af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com 9449f085dddff10473b6ebf832a974288300224e60bsalomon if (fCachedImage) { 9597af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com // the surface may need to fork its backend, if its sharing it with 9697af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com // the cached image. Note: we only call if there is an outstanding owner 9797af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com // on the image (besides us). 98f64c6842c15e1ba126639be7578e4642cb396987bungeman@google.com if (!fCachedImage->unique()) { 99c4c9870953037be94da00ac9db887d171f6e479ccommit-bot@chromium.org this->onCopyOnWrite(mode); 10097af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com } 10197af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com 10297af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com // regardless of copy-on-write, we must drop our cached image now, so 10397af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com // that the next request will get our new contents. 10497af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com fCachedImage->unref(); 10597af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com fCachedImage = NULL; 10628361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org } else if (kDiscard_ContentChangeMode == mode) { 10728361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org this->onDiscard(); 10897af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com } 10997af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com} 11097af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com 11197af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.comuint32_t SkSurface_Base::newGenerationID() { 11228361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org SkASSERT(!fCachedCanvas || fCachedCanvas->getSurfaceBase() == this); 11397af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com static int32_t gID; 11497af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com return sk_atomic_inc(&gID) + 1; 11597af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com} 11697af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com 117889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.comstatic SkSurface_Base* asSB(SkSurface* surface) { 118889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com return static_cast<SkSurface_Base*>(surface); 119889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com} 120889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com 121889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com/////////////////////////////////////////////////////////////////////////////// 122889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com 1234a8126e7f81384526629b1e21bf89b632ea13cd9reedSkSurface::SkSurface(int width, int height, const SkSurfaceProps* props) 1244a8126e7f81384526629b1e21bf89b632ea13cd9reed : fProps(SkSurfacePropsCopyOrDefault(props)), fWidth(width), fHeight(height) 1254a8126e7f81384526629b1e21bf89b632ea13cd9reed{ 126b2497c2d945c0a5d770865b026e2d5947bf37c91reed SkASSERT(fWidth > 0); 127b2497c2d945c0a5d770865b026e2d5947bf37c91reed SkASSERT(fHeight > 0); 1281360c52b10dad45d7a6850370eab40c6253d7988reed@google.com fGenerationID = 0; 1291360c52b10dad45d7a6850370eab40c6253d7988reed@google.com} 1301360c52b10dad45d7a6850370eab40c6253d7988reed@google.com 1314a8126e7f81384526629b1e21bf89b632ea13cd9reedSkSurface::SkSurface(const SkImageInfo& info, const SkSurfaceProps* props) 1324a8126e7f81384526629b1e21bf89b632ea13cd9reed : fProps(SkSurfacePropsCopyOrDefault(props)), fWidth(info.width()), fHeight(info.height()) 1334a8126e7f81384526629b1e21bf89b632ea13cd9reed{ 134b2497c2d945c0a5d770865b026e2d5947bf37c91reed SkASSERT(fWidth > 0); 135b2497c2d945c0a5d770865b026e2d5947bf37c91reed SkASSERT(fHeight > 0); 136889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com fGenerationID = 0; 137889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com} 138889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com 13997af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.comuint32_t SkSurface::generationID() { 14097af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com if (0 == fGenerationID) { 14197af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com fGenerationID = asSB(this)->newGenerationID(); 14297af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com } 14397af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com return fGenerationID; 14497af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com} 14597af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com 146c4c9870953037be94da00ac9db887d171f6e479ccommit-bot@chromium.orgvoid SkSurface::notifyContentWillChange(ContentChangeMode mode) { 147c4c9870953037be94da00ac9db887d171f6e479ccommit-bot@chromium.org asSB(this)->aboutToDraw(mode); 14897af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com} 14997af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com 1509ea5a3bc7361cb88d37280b5922fba9430fed328reed@google.comSkCanvas* SkSurface::getCanvas() { 1519ea5a3bc7361cb88d37280b5922fba9430fed328reed@google.com return asSB(this)->getCachedCanvas(); 152889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com} 153889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com 154eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomonSkImage* SkSurface::newImageSnapshot(Budgeted budgeted) { 155eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon SkImage* image = asSB(this)->getCachedImage(budgeted); 15697af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com SkSafeRef(image); // the caller will call unref() to balance this 15797af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com return image; 158889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com} 159889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com 1602bd8b8100529c96c81c30f749f672f4caf775b04reed@google.comSkSurface* SkSurface::newSurface(const SkImageInfo& info) { 161b947625800a26194fcf63d7b57dadb1a63677f6amike@reedtribe.org return asSB(this)->onNewSurface(info); 162889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com} 163889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com 164889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.comvoid SkSurface::draw(SkCanvas* canvas, SkScalar x, SkScalar y, 165889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com const SkPaint* paint) { 166889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com return asSB(this)->onDraw(canvas, x, y, paint); 167889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com} 168c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 169c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.orgconst void* SkSurface::peekPixels(SkImageInfo* info, size_t* rowBytes) { 170c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org return this->getCanvas()->peekPixels(info, rowBytes); 171c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1724a8126e7f81384526629b1e21bf89b632ea13cd9reed 1737543aa2b365abfc968bd84ee32247ac51f904608reedbool SkSurface::readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes, 1747543aa2b365abfc968bd84ee32247ac51f904608reed int srcX, int srcY) { 1757543aa2b365abfc968bd84ee32247ac51f904608reed return this->getCanvas()->readPixels(dstInfo, dstPixels, dstRowBytes, srcX, srcY); 1767543aa2b365abfc968bd84ee32247ac51f904608reed} 1777543aa2b365abfc968bd84ee32247ac51f904608reed 1784a8126e7f81384526629b1e21bf89b632ea13cd9reed////////////////////////////////////////////////////////////////////////////////////// 1794a8126e7f81384526629b1e21bf89b632ea13cd9reed 1804a8126e7f81384526629b1e21bf89b632ea13cd9reed#if !SK_SUPPORT_GPU 1814a8126e7f81384526629b1e21bf89b632ea13cd9reed 1824a8126e7f81384526629b1e21bf89b632ea13cd9reedSkSurface* SkSurface::NewRenderTargetDirect(GrRenderTarget*, const SkSurfaceProps*) { 1834a8126e7f81384526629b1e21bf89b632ea13cd9reed return NULL; 1844a8126e7f81384526629b1e21bf89b632ea13cd9reed} 1854a8126e7f81384526629b1e21bf89b632ea13cd9reed 186afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomonSkSurface* SkSurface::NewRenderTarget(GrContext*, Budgeted, const SkImageInfo&, int, 187afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon const SkSurfaceProps*) { 1884a8126e7f81384526629b1e21bf89b632ea13cd9reed return NULL; 1894a8126e7f81384526629b1e21bf89b632ea13cd9reed} 1904a8126e7f81384526629b1e21bf89b632ea13cd9reed 191e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomonSkSurface* SkSurface::NewWrappedRenderTarget(GrContext*, GrBackendTextureDesc, 192e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon const SkSurfaceProps*) { 193e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon return NULL; 194e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon} 1954a8126e7f81384526629b1e21bf89b632ea13cd9reed 1964a8126e7f81384526629b1e21bf89b632ea13cd9reed#endif 197