1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2010 Google Inc. 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 6ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com */ 7ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 8ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#include "SkGr.h" 98dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org#include "SkColorFilter.h" 10ea476e1725f38688b79aadf4c5e36c10c3141927commit-bot@chromium.org#include "SkConfig8888.h" 119c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski#include "SkData.h" 1250a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org#include "SkMessageBus.h" 1350a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org#include "SkPixelRef.h" 1440a1e11ebebe81586f3fec96408fdfd4b51123d2krajcevski#include "SkTextureCompressor.h" 1550a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org#include "GrResourceCache.h" 169c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski#include "GrGpu.h" 17f461a8fdf642ba713dcdfb217534652df1eac278krajcevski#include "effects/GrDitherEffect.h" 189c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski#include "GrDrawTargetCaps.h" 19518d83dbc1c899e316e8c896af5defb58b83120fsugoi#include "effects/GrYUVtoRGBEffect.h" 209c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski 218c111f783f40470e697310244426362132979ad9krajcevski#ifndef SK_IGNORE_ETC1_SUPPORT 2299ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski# include "ktx.h" 239c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski# include "etc1.h" 249c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski#endif 25ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 26ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com/* Fill out buffer with the compressed format Ganesh expects from a colortable 27ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com based bitmap. [palette (colortable) + indices]. 285782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com 295782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com At the moment Ganesh only supports 8bit version. If Ganesh allowed we others 30ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com we could detect that the colortable.count is <= 16, and then repack the 31ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com indices as nibbles to save RAM, but it would take more time (i.e. a lot 32ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com slower than memcpy), so skipping that for now. 335782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com 34ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com Ganesh wants a full 256 palette entry, even though Skia's ctable is only as big 35ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com as the colortable.count says it is. 36ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com */ 37ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comstatic void build_compressed_data(void* buffer, const SkBitmap& bitmap) { 380689d7b12e7c427a077b003d3d8ae759d86f798freed SkASSERT(kIndex_8_SkColorType == bitmap.colorType()); 395782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com 407f4ad5a30ff745e666579d2b518dfd0c1aa49596bsalomon@google.com SkAutoLockPixels alp(bitmap); 41ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com if (!bitmap.readyToDraw()) { 420c00f21fee3f5cfa3aa7e5d46ff94cb8cf340451tomhudson@google.com SkDEBUGFAIL("bitmap not ready to draw!"); 43ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com return; 44ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 45ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 46ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com SkColorTable* ctable = bitmap.getColorTable(); 47ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com char* dst = (char*)buffer; 485782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com 497111d463cee893a479280c7af41757e709e33ef5reed@google.com const int count = ctable->count(); 507111d463cee893a479280c7af41757e709e33ef5reed@google.com 517111d463cee893a479280c7af41757e709e33ef5reed@google.com SkDstPixelInfo dstPI; 527111d463cee893a479280c7af41757e709e33ef5reed@google.com dstPI.fColorType = kRGBA_8888_SkColorType; 537111d463cee893a479280c7af41757e709e33ef5reed@google.com dstPI.fAlphaType = kPremul_SkAlphaType; 547111d463cee893a479280c7af41757e709e33ef5reed@google.com dstPI.fPixels = buffer; 557111d463cee893a479280c7af41757e709e33ef5reed@google.com dstPI.fRowBytes = count * sizeof(SkPMColor); 567111d463cee893a479280c7af41757e709e33ef5reed@google.com 577111d463cee893a479280c7af41757e709e33ef5reed@google.com SkSrcPixelInfo srcPI; 5828fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org srcPI.fColorType = kN32_SkColorType; 597111d463cee893a479280c7af41757e709e33ef5reed@google.com srcPI.fAlphaType = kPremul_SkAlphaType; 607111d463cee893a479280c7af41757e709e33ef5reed@google.com srcPI.fPixels = ctable->lockColors(); 617111d463cee893a479280c7af41757e709e33ef5reed@google.com srcPI.fRowBytes = count * sizeof(SkPMColor); 627111d463cee893a479280c7af41757e709e33ef5reed@google.com 637111d463cee893a479280c7af41757e709e33ef5reed@google.com srcPI.convertPixelsTo(&dstPI, count, 1); 647111d463cee893a479280c7af41757e709e33ef5reed@google.com 650a6151d66cc32d91eca037c91e557158cf8a2be2reed@google.com ctable->unlockColors(); 665782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com 67ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com // always skip a full 256 number of entries, even if we memcpy'd fewer 68d4cb922ea1a85d381e88975b63664f6c0bf28cdbbsalomon dst += 256 * sizeof(GrColor); 69ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 700ba4bf427acbd7707d04192a98c77ef194a0f25ascroggo@google.com if ((unsigned)bitmap.width() == bitmap.rowBytes()) { 71ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com memcpy(dst, bitmap.getPixels(), bitmap.getSize()); 72ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } else { 73ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com // need to trim off the extra bytes per row 74ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com size_t width = bitmap.width(); 75ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com size_t rowBytes = bitmap.rowBytes(); 76ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com const char* src = (const char*)bitmap.getPixels(); 77ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com for (int y = 0; y < bitmap.height(); y++) { 78ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com memcpy(dst, src, width); 79ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com src += rowBytes; 80ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com dst += width; 81ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 82ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 83ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 84ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 85ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com//////////////////////////////////////////////////////////////////////////////// 86ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 870797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.comstatic void generate_bitmap_cache_id(const SkBitmap& bitmap, GrCacheID* id) { 880797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com // Our id includes the offset, width, and height so that bitmaps created by extractSubset() 890797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com // are unique. 900797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com uint32_t genID = bitmap.getGenerationID(); 91672588b684d484dce6ae251e9e163e4a46924322reed@google.com SkIPoint origin = bitmap.pixelRefOrigin(); 92672588b684d484dce6ae251e9e163e4a46924322reed@google.com int16_t width = SkToS16(bitmap.width()); 93672588b684d484dce6ae251e9e163e4a46924322reed@google.com int16_t height = SkToS16(bitmap.height()); 940797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com 952859eb74f9c87471b2429cd12b84144b97157efbskia.committer@gmail.com GrCacheID::Key key; 96672588b684d484dce6ae251e9e163e4a46924322reed@google.com memcpy(key.fData8 + 0, &genID, 4); 97672588b684d484dce6ae251e9e163e4a46924322reed@google.com memcpy(key.fData8 + 4, &origin.fX, 4); 98672588b684d484dce6ae251e9e163e4a46924322reed@google.com memcpy(key.fData8 + 8, &origin.fY, 4); 99672588b684d484dce6ae251e9e163e4a46924322reed@google.com memcpy(key.fData8 + 12, &width, 2); 100672588b684d484dce6ae251e9e163e4a46924322reed@google.com memcpy(key.fData8 + 14, &height, 2); 101672588b684d484dce6ae251e9e163e4a46924322reed@google.com static const size_t kKeyDataSize = 16; 10210a9fb86a9cd11f7fd590410e2aa0906587555e6bsalomon@google.com memset(key.fData8 + kKeyDataSize, 0, sizeof(key) - kKeyDataSize); 103672588b684d484dce6ae251e9e163e4a46924322reed@google.com GR_STATIC_ASSERT(sizeof(key) >= kKeyDataSize); 1040797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com static const GrCacheID::Domain gBitmapTextureDomain = GrCacheID::GenerateDomain(); 1050797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com id->reset(gBitmapTextureDomain, key); 1060797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com} 1070797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com 1080797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.comstatic void generate_bitmap_texture_desc(const SkBitmap& bitmap, GrTextureDesc* desc) { 1090797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com desc->fFlags = kNone_GrTextureFlags; 1100797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com desc->fWidth = bitmap.width(); 1110797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com desc->fHeight = bitmap.height(); 1123adcc3403377c0b9a7afde6db8e0432325413a10commit-bot@chromium.org desc->fConfig = SkImageInfo2GrPixelConfig(bitmap.info()); 1130797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com desc->fSampleCnt = 0; 1140797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com} 1150797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com 11650a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.orgnamespace { 11750a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org 11850a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org// When the SkPixelRef genID changes, invalidate a corresponding GrResource described by key. 11950a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.orgclass GrResourceInvalidator : public SkPixelRef::GenIDChangeListener { 12050a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.orgpublic: 12150a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org explicit GrResourceInvalidator(GrResourceKey key) : fKey(key) {} 12250a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.orgprivate: 12350a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org GrResourceKey fKey; 12450a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org 12550a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org virtual void onChange() SK_OVERRIDE { 12650a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org const GrResourceInvalidatedMessage message = { fKey }; 12750a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org SkMessageBus<GrResourceInvalidatedMessage>::Post(message); 12850a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org } 12950a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org}; 13050a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org 13150a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org} // namespace 13250a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org 13350a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.orgstatic void add_genID_listener(GrResourceKey key, SkPixelRef* pixelRef) { 13449f085dddff10473b6ebf832a974288300224e60bsalomon SkASSERT(pixelRef); 13550a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org pixelRef->addGenIDChangeListener(SkNEW_ARGS(GrResourceInvalidator, (key))); 13650a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org} 13750a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org 1380249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoistatic GrTexture* sk_gr_allocate_texture(GrContext* ctx, 1390249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi bool cache, 1400249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi const GrTextureParams* params, 1410249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi const SkBitmap& bm, 14277cd8b0ba20bca3a9d994586eb58337bcf2082fbbungeman GrTextureDesc desc, 1430249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi const void* pixels, 1440249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi size_t rowBytes) { 1450249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi GrTexture* result; 1460249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi if (cache) { 1470249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi // This texture is likely to be used again so leave it in the cache 1480249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi GrCacheID cacheID; 1490249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi generate_bitmap_cache_id(bm, &cacheID); 1500249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi 1510249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi GrResourceKey key; 1520249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi result = ctx->createTexture(params, desc, cacheID, pixels, rowBytes, &key); 1530249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi if (result) { 1540249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi add_genID_listener(key, bm.pixelRef()); 1550249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi } 1560249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi } else { 1570249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi // This texture is unlikely to be used again (in its present form) so 1580249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi // just use a scratch texture. This will remove the texture from the 1590249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi // cache so no one else can find it. Additionally, once unlocked, the 1600249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi // scratch texture will go to the end of the list for purging so will 1610249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi // likely be available for this volatile bitmap the next time around. 1620249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi result = ctx->lockAndRefScratchTexture(desc, GrContext::kExact_ScratchTexMatch); 1630249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi if (pixels) { 1640249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi result->writePixels(0, 0, bm.width(), bm.height(), desc.fConfig, pixels, rowBytes); 1650249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi } 1660249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi } 1670249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi return result; 1680249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi} 1690249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi 1708c111f783f40470e697310244426362132979ad9krajcevski#ifndef SK_IGNORE_ETC1_SUPPORT 1710249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoistatic GrTexture *load_etc1_texture(GrContext* ctx, bool cache, 1729c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski const GrTextureParams* params, 1739c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski const SkBitmap &bm, GrTextureDesc desc) { 17499ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski SkAutoTUnref<SkData> data(bm.pixelRef()->refEncodedData()); 1759c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski 1769c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski // Is this even encoded data? 1779c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski if (NULL == data) { 1789c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski return NULL; 1799c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski } 1809c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski 1819c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski // Is this a valid PKM encoded data? 1829c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski const uint8_t *bytes = data->bytes(); 18399ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski if (etc1_pkm_is_valid(bytes)) { 18499ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski uint32_t encodedWidth = etc1_pkm_get_width(bytes); 18599ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski uint32_t encodedHeight = etc1_pkm_get_height(bytes); 18699ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski 18799ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski // Does the data match the dimensions of the bitmap? If not, 18899ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski // then we don't know how to scale the image to match it... 18999ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski if (encodedWidth != static_cast<uint32_t>(bm.width()) || 19099ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski encodedHeight != static_cast<uint32_t>(bm.height())) { 19199ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski return NULL; 19299ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski } 19399ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski 19499ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski // Everything seems good... skip ahead to the data. 19599ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski bytes += ETC_PKM_HEADER_SIZE; 19699ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski desc.fConfig = kETC1_GrPixelConfig; 19799ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski } else if (SkKTXFile::is_ktx(bytes)) { 19899ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski SkKTXFile ktx(data); 1999c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski 20099ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski // Is it actually an ETC1 texture? 20140a1e11ebebe81586f3fec96408fdfd4b51123d2krajcevski if (!ktx.isCompressedFormat(SkTextureCompressor::kETC1_Format)) { 20299ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski return NULL; 20399ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski } 20499ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski 20599ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski // Does the data match the dimensions of the bitmap? If not, 20699ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski // then we don't know how to scale the image to match it... 20799ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski if (ktx.width() != bm.width() || ktx.height() != bm.height()) { 20899ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski return NULL; 20999ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski } 2109c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski 21199ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski bytes = ktx.pixelData(); 21299ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski desc.fConfig = kETC1_GrPixelConfig; 21399ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski } else { 2149c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski return NULL; 2159c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski } 2169c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski 2170249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi return sk_gr_allocate_texture(ctx, cache, params, bm, desc, bytes, 0); 2189c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski} 2198c111f783f40470e697310244426362132979ad9krajcevski#endif // SK_IGNORE_ETC1_SUPPORT 2209c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski 2210249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoistatic GrTexture *load_yuv_texture(GrContext* ctx, bool cache, const GrTextureParams* params, 222518d83dbc1c899e316e8c896af5defb58b83120fsugoi const SkBitmap& bm, const GrTextureDesc& desc) { 223518d83dbc1c899e316e8c896af5defb58b83120fsugoi SkPixelRef* pixelRef = bm.pixelRef(); 224518d83dbc1c899e316e8c896af5defb58b83120fsugoi SkISize yuvSizes[3]; 225abaef86f2b37d8a939506a2076da07f6db456951rileya if ((NULL == pixelRef) || !pixelRef->getYUV8Planes(yuvSizes, NULL, NULL, NULL)) { 226518d83dbc1c899e316e8c896af5defb58b83120fsugoi return NULL; 227518d83dbc1c899e316e8c896af5defb58b83120fsugoi } 228518d83dbc1c899e316e8c896af5defb58b83120fsugoi 229518d83dbc1c899e316e8c896af5defb58b83120fsugoi // Allocate the memory for YUV 230518d83dbc1c899e316e8c896af5defb58b83120fsugoi size_t totalSize(0); 231518d83dbc1c899e316e8c896af5defb58b83120fsugoi size_t sizes[3], rowBytes[3]; 232518d83dbc1c899e316e8c896af5defb58b83120fsugoi for (int i = 0; i < 3; ++i) { 233518d83dbc1c899e316e8c896af5defb58b83120fsugoi rowBytes[i] = yuvSizes[i].fWidth; 234518d83dbc1c899e316e8c896af5defb58b83120fsugoi totalSize += sizes[i] = rowBytes[i] * yuvSizes[i].fHeight; 235518d83dbc1c899e316e8c896af5defb58b83120fsugoi } 236518d83dbc1c899e316e8c896af5defb58b83120fsugoi SkAutoMalloc storage(totalSize); 237518d83dbc1c899e316e8c896af5defb58b83120fsugoi void* planes[3]; 238518d83dbc1c899e316e8c896af5defb58b83120fsugoi planes[0] = storage.get(); 239518d83dbc1c899e316e8c896af5defb58b83120fsugoi planes[1] = (uint8_t*)planes[0] + sizes[0]; 240518d83dbc1c899e316e8c896af5defb58b83120fsugoi planes[2] = (uint8_t*)planes[1] + sizes[1]; 241518d83dbc1c899e316e8c896af5defb58b83120fsugoi 242abaef86f2b37d8a939506a2076da07f6db456951rileya SkYUVColorSpace colorSpace; 243abaef86f2b37d8a939506a2076da07f6db456951rileya 244518d83dbc1c899e316e8c896af5defb58b83120fsugoi // Get the YUV planes 245abaef86f2b37d8a939506a2076da07f6db456951rileya if (!pixelRef->getYUV8Planes(yuvSizes, planes, rowBytes, &colorSpace)) { 246518d83dbc1c899e316e8c896af5defb58b83120fsugoi return NULL; 247518d83dbc1c899e316e8c896af5defb58b83120fsugoi } 248518d83dbc1c899e316e8c896af5defb58b83120fsugoi 249518d83dbc1c899e316e8c896af5defb58b83120fsugoi GrTextureDesc yuvDesc; 250518d83dbc1c899e316e8c896af5defb58b83120fsugoi yuvDesc.fConfig = kAlpha_8_GrPixelConfig; 251518d83dbc1c899e316e8c896af5defb58b83120fsugoi GrAutoScratchTexture yuvTextures[3]; 252518d83dbc1c899e316e8c896af5defb58b83120fsugoi for (int i = 0; i < 3; ++i) { 253518d83dbc1c899e316e8c896af5defb58b83120fsugoi yuvDesc.fWidth = yuvSizes[i].fWidth; 254518d83dbc1c899e316e8c896af5defb58b83120fsugoi yuvDesc.fHeight = yuvSizes[i].fHeight; 255518d83dbc1c899e316e8c896af5defb58b83120fsugoi yuvTextures[i].set(ctx, yuvDesc); 256518d83dbc1c899e316e8c896af5defb58b83120fsugoi if ((NULL == yuvTextures[i].texture()) || 257518d83dbc1c899e316e8c896af5defb58b83120fsugoi !ctx->writeTexturePixels(yuvTextures[i].texture(), 258518d83dbc1c899e316e8c896af5defb58b83120fsugoi 0, 0, yuvDesc.fWidth, yuvDesc.fHeight, 259518d83dbc1c899e316e8c896af5defb58b83120fsugoi yuvDesc.fConfig, planes[i], rowBytes[i])) { 260518d83dbc1c899e316e8c896af5defb58b83120fsugoi return NULL; 261518d83dbc1c899e316e8c896af5defb58b83120fsugoi } 262518d83dbc1c899e316e8c896af5defb58b83120fsugoi } 263518d83dbc1c899e316e8c896af5defb58b83120fsugoi 264518d83dbc1c899e316e8c896af5defb58b83120fsugoi GrTextureDesc rtDesc = desc; 265518d83dbc1c899e316e8c896af5defb58b83120fsugoi rtDesc.fFlags = rtDesc.fFlags | 266518d83dbc1c899e316e8c896af5defb58b83120fsugoi kRenderTarget_GrTextureFlagBit | 267518d83dbc1c899e316e8c896af5defb58b83120fsugoi kNoStencil_GrTextureFlagBit; 268518d83dbc1c899e316e8c896af5defb58b83120fsugoi 2690249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi GrTexture* result = sk_gr_allocate_texture(ctx, cache, params, bm, rtDesc, NULL, 0); 270518d83dbc1c899e316e8c896af5defb58b83120fsugoi 271518d83dbc1c899e316e8c896af5defb58b83120fsugoi GrRenderTarget* renderTarget = result ? result->asRenderTarget() : NULL; 27249f085dddff10473b6ebf832a974288300224e60bsalomon if (renderTarget) { 273b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt SkAutoTUnref<GrFragmentProcessor> yuvToRgbProcessor(GrYUVtoRGBEffect::Create( 274abaef86f2b37d8a939506a2076da07f6db456951rileya yuvTextures[0].texture(), yuvTextures[1].texture(), yuvTextures[2].texture(), 275abaef86f2b37d8a939506a2076da07f6db456951rileya colorSpace)); 276518d83dbc1c899e316e8c896af5defb58b83120fsugoi GrPaint paint; 277b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt paint.addColorProcessor(yuvToRgbProcessor); 278518d83dbc1c899e316e8c896af5defb58b83120fsugoi SkRect r = SkRect::MakeWH(SkIntToScalar(yuvSizes[0].fWidth), 279518d83dbc1c899e316e8c896af5defb58b83120fsugoi SkIntToScalar(yuvSizes[0].fHeight)); 280518d83dbc1c899e316e8c896af5defb58b83120fsugoi GrContext::AutoRenderTarget autoRT(ctx, renderTarget); 281518d83dbc1c899e316e8c896af5defb58b83120fsugoi GrContext::AutoMatrix am; 282518d83dbc1c899e316e8c896af5defb58b83120fsugoi am.setIdentity(ctx); 283518d83dbc1c899e316e8c896af5defb58b83120fsugoi GrContext::AutoClip ac(ctx, GrContext::AutoClip::kWideOpen_InitialClip); 284518d83dbc1c899e316e8c896af5defb58b83120fsugoi ctx->drawRect(paint, r); 285518d83dbc1c899e316e8c896af5defb58b83120fsugoi } else { 286518d83dbc1c899e316e8c896af5defb58b83120fsugoi SkSafeSetNull(result); 287518d83dbc1c899e316e8c896af5defb58b83120fsugoi } 288518d83dbc1c899e316e8c896af5defb58b83120fsugoi 289518d83dbc1c899e316e8c896af5defb58b83120fsugoi return result; 290518d83dbc1c899e316e8c896af5defb58b83120fsugoi} 291518d83dbc1c899e316e8c896af5defb58b83120fsugoi 2921f47f4f7325971dd53991e2bb02da94fa7c6d962robertphillips@google.comstatic GrTexture* sk_gr_create_bitmap_texture(GrContext* ctx, 2930797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com bool cache, 2941f47f4f7325971dd53991e2bb02da94fa7c6d962robertphillips@google.com const GrTextureParams* params, 2951f47f4f7325971dd53991e2bb02da94fa7c6d962robertphillips@google.com const SkBitmap& origBitmap) { 296ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com SkBitmap tmpBitmap; 297ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 298ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com const SkBitmap* bitmap = &origBitmap; 2995782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com 30075b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com GrTextureDesc desc; 3010797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com generate_bitmap_texture_desc(*bitmap, &desc); 3025782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com 3030689d7b12e7c427a077b003d3d8ae759d86f798freed if (kIndex_8_SkColorType == bitmap->colorType()) { 304ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com // build_compressed_data doesn't do npot->pot expansion 305ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com // and paletted textures can't be sub-updated 3067f4ad5a30ff745e666579d2b518dfd0c1aa49596bsalomon@google.com if (ctx->supportsIndex8PixelConfig(params, bitmap->width(), bitmap->height())) { 307d4cb922ea1a85d381e88975b63664f6c0bf28cdbbsalomon size_t imageSize = GrCompressedFormatDataSize(kIndex_8_GrPixelConfig, 308d4cb922ea1a85d381e88975b63664f6c0bf28cdbbsalomon bitmap->width(), bitmap->height()); 309d4cb922ea1a85d381e88975b63664f6c0bf28cdbbsalomon SkAutoMalloc storage(imageSize); 3105782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com 311ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com build_compressed_data(storage.get(), origBitmap); 312ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 313ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com // our compressed data will be trimmed, so pass width() for its 314ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com // "rowBytes", since they are the same now. 3150249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi return sk_gr_allocate_texture(ctx, cache, params, origBitmap, 3160249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi desc, storage.get(), bitmap->width()); 317ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } else { 31828fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org origBitmap.copyTo(&tmpBitmap, kN32_SkColorType); 319ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com // now bitmap points to our temp, which has been promoted to 32bits 320ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com bitmap = &tmpBitmap; 3213adcc3403377c0b9a7afde6db8e0432325413a10commit-bot@chromium.org desc.fConfig = SkImageInfo2GrPixelConfig(bitmap->info()); 322ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 323309e86912445879651d52ebbedb67b4ff3f1516ckrajcevski } 3249c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski 3259c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski // Is this an ETC1 encoded texture? 3268c111f783f40470e697310244426362132979ad9krajcevski#ifndef SK_IGNORE_ETC1_SUPPORT 3279a3cdbb3d0957ad3f04d02277a4ce839752f4efdkrajcevski else if ( 32877cd8b0ba20bca3a9d994586eb58337bcf2082fbbungeman // We do not support scratch ETC1 textures, hence they should all be at least 32977cd8b0ba20bca3a9d994586eb58337bcf2082fbbungeman // trying to go to the cache. 33077cd8b0ba20bca3a9d994586eb58337bcf2082fbbungeman cache 3319a3cdbb3d0957ad3f04d02277a4ce839752f4efdkrajcevski // Make sure that the underlying device supports ETC1 textures before we go ahead 3329a3cdbb3d0957ad3f04d02277a4ce839752f4efdkrajcevski // and check the data. 33377cd8b0ba20bca3a9d994586eb58337bcf2082fbbungeman && ctx->getGpu()->caps()->isConfigTexturable(kETC1_GrPixelConfig) 3349a3cdbb3d0957ad3f04d02277a4ce839752f4efdkrajcevski // If the bitmap had compressed data and was then uncompressed, it'll still return 3359a3cdbb3d0957ad3f04d02277a4ce839752f4efdkrajcevski // compressed data on 'refEncodedData' and upload it. Probably not good, since if 3369a3cdbb3d0957ad3f04d02277a4ce839752f4efdkrajcevski // the bitmap has available pixels, then they might not be what the decompressed 3379a3cdbb3d0957ad3f04d02277a4ce839752f4efdkrajcevski // data is. 3389a3cdbb3d0957ad3f04d02277a4ce839752f4efdkrajcevski && !(bitmap->readyToDraw())) { 3390249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi GrTexture *texture = load_etc1_texture(ctx, cache, params, *bitmap, desc); 34049f085dddff10473b6ebf832a974288300224e60bsalomon if (texture) { 3419c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski return texture; 3429c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski } 3435782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com } 3448c111f783f40470e697310244426362132979ad9krajcevski#endif // SK_IGNORE_ETC1_SUPPORT 345ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 346518d83dbc1c899e316e8c896af5defb58b83120fsugoi else { 3470249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi GrTexture *texture = load_yuv_texture(ctx, cache, params, *bitmap, desc); 34849f085dddff10473b6ebf832a974288300224e60bsalomon if (texture) { 349518d83dbc1c899e316e8c896af5defb58b83120fsugoi return texture; 350518d83dbc1c899e316e8c896af5defb58b83120fsugoi } 351518d83dbc1c899e316e8c896af5defb58b83120fsugoi } 3527f4ad5a30ff745e666579d2b518dfd0c1aa49596bsalomon@google.com SkAutoLockPixels alp(*bitmap); 3537f4ad5a30ff745e666579d2b518dfd0c1aa49596bsalomon@google.com if (!bitmap->readyToDraw()) { 3547f4ad5a30ff745e666579d2b518dfd0c1aa49596bsalomon@google.com return NULL; 3557f4ad5a30ff745e666579d2b518dfd0c1aa49596bsalomon@google.com } 35650a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org 3570249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi return sk_gr_allocate_texture(ctx, cache, params, origBitmap, desc, 3580249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi bitmap->getPixels(), bitmap->rowBytes()); 359ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 360ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 3610797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.combool GrIsBitmapInCache(const GrContext* ctx, 3620797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com const SkBitmap& bitmap, 3630797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com const GrTextureParams* params) { 3640797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com GrCacheID cacheID; 3650797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com generate_bitmap_cache_id(bitmap, &cacheID); 3660797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com 3670797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com GrTextureDesc desc; 3680797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com generate_bitmap_texture_desc(bitmap, &desc); 3690797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com return ctx->isTextureInCache(desc, cacheID, params); 3700797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com} 371ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 37295ed55adc6b8f0cee063c2cf2e14782773b0087fbsalomon@google.comGrTexture* GrLockAndRefCachedBitmapTexture(GrContext* ctx, 37395ed55adc6b8f0cee063c2cf2e14782773b0087fbsalomon@google.com const SkBitmap& bitmap, 37495ed55adc6b8f0cee063c2cf2e14782773b0087fbsalomon@google.com const GrTextureParams* params) { 3751f47f4f7325971dd53991e2bb02da94fa7c6d962robertphillips@google.com GrTexture* result = NULL; 37624f3ad1bbb44916cae33f5d3cf2a20af4bbc381frileya@google.com 3770797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com bool cache = !bitmap.isVolatile(); 3789c2ea846351a29208cb4a36301ee611e7fb384earobertphillips@google.com 3790797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com if (cache) { 3800797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com // If the bitmap isn't changing try to find a cached copy first. 3814b86e3428b115202e82d49a0914ea8ab6dc25940bsalomon@google.com 3820797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com GrCacheID cacheID; 3830797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com generate_bitmap_cache_id(bitmap, &cacheID); 3840b6ad2297fbf43466950690102c1c9c150f2a972bsalomon@google.com 3850797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com GrTextureDesc desc; 3860797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com generate_bitmap_texture_desc(bitmap, &desc); 3870797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com 38895ed55adc6b8f0cee063c2cf2e14782773b0087fbsalomon@google.com result = ctx->findAndRefTexture(desc, cacheID, params); 3890797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com } 3900797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com if (NULL == result) { 3910797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com result = sk_gr_create_bitmap_texture(ctx, cache, params, bitmap); 39224f3ad1bbb44916cae33f5d3cf2a20af4bbc381frileya@google.com } 3931f47f4f7325971dd53991e2bb02da94fa7c6d962robertphillips@google.com if (NULL == result) { 39424f3ad1bbb44916cae33f5d3cf2a20af4bbc381frileya@google.com GrPrintf("---- failed to create texture for cache [%d %d]\n", 39524f3ad1bbb44916cae33f5d3cf2a20af4bbc381frileya@google.com bitmap.width(), bitmap.height()); 39624f3ad1bbb44916cae33f5d3cf2a20af4bbc381frileya@google.com } 3971f47f4f7325971dd53991e2bb02da94fa7c6d962robertphillips@google.com return result; 39824f3ad1bbb44916cae33f5d3cf2a20af4bbc381frileya@google.com} 39924f3ad1bbb44916cae33f5d3cf2a20af4bbc381frileya@google.com 40095ed55adc6b8f0cee063c2cf2e14782773b0087fbsalomon@google.comvoid GrUnlockAndUnrefCachedBitmapTexture(GrTexture* texture) { 40149f085dddff10473b6ebf832a974288300224e60bsalomon SkASSERT(texture->getContext()); 4021f47f4f7325971dd53991e2bb02da94fa7c6d962robertphillips@google.com 4039fbcad0f00d7098574cf3394a812c9d845c9cc5brobertphillips@google.com texture->getContext()->unlockScratchTexture(texture); 40495ed55adc6b8f0cee063c2cf2e14782773b0087fbsalomon@google.com texture->unref(); 40524f3ad1bbb44916cae33f5d3cf2a20af4bbc381frileya@google.com} 40624f3ad1bbb44916cae33f5d3cf2a20af4bbc381frileya@google.com 40724f3ad1bbb44916cae33f5d3cf2a20af4bbc381frileya@google.com/////////////////////////////////////////////////////////////////////////////// 40824f3ad1bbb44916cae33f5d3cf2a20af4bbc381frileya@google.com 40915a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org// alphatype is ignore for now, but if GrPixelConfig is expanded to encompass 41015a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org// alpha info, that will be considered. 41115a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.orgGrPixelConfig SkImageInfo2GrPixelConfig(SkColorType ct, SkAlphaType) { 41215a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org switch (ct) { 41315a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org case kUnknown_SkColorType: 41415a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org return kUnknown_GrPixelConfig; 41515a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org case kAlpha_8_SkColorType: 41615a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org return kAlpha_8_GrPixelConfig; 41715a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org case kRGB_565_SkColorType: 41815a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org return kRGB_565_GrPixelConfig; 41915a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org case kARGB_4444_SkColorType: 42015a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org return kRGBA_4444_GrPixelConfig; 42115a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org case kRGBA_8888_SkColorType: 42215a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org return kRGBA_8888_GrPixelConfig; 42315a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org case kBGRA_8888_SkColorType: 42415a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org return kBGRA_8888_GrPixelConfig; 42515a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org case kIndex_8_SkColorType: 42615a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org return kIndex_8_GrPixelConfig; 42715a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org } 42815a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org SkASSERT(0); // shouldn't get here 42915a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org return kUnknown_GrPixelConfig; 43015a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org} 43115a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org 432bf790232f6d94b54239dbc210d8beee7411ca458reed@google.combool GrPixelConfig2ColorType(GrPixelConfig config, SkColorType* ctOut) { 433bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com SkColorType ct; 434bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com switch (config) { 435bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com case kAlpha_8_GrPixelConfig: 436bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com ct = kAlpha_8_SkColorType; 437bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com break; 438bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com case kIndex_8_GrPixelConfig: 439bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com ct = kIndex_8_SkColorType; 440bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com break; 441bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com case kRGB_565_GrPixelConfig: 442bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com ct = kRGB_565_SkColorType; 443bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com break; 444bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com case kRGBA_4444_GrPixelConfig: 445bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com ct = kARGB_4444_SkColorType; 446bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com break; 447bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com case kRGBA_8888_GrPixelConfig: 448bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com ct = kRGBA_8888_SkColorType; 449bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com break; 450bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com case kBGRA_8888_GrPixelConfig: 451bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com ct = kBGRA_8888_SkColorType; 452bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com break; 453bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com default: 454bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com return false; 455bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com } 456bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com if (ctOut) { 457bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com *ctOut = ct; 458bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com } 459bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com return true; 460bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com} 4618dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org 4628dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 4638dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org 46483d081ae1d731b5039e99823620f5e287542ee39bsalomonvoid SkPaint2GrPaintNoShader(GrContext* context, const SkPaint& skPaint, GrColor paintColor, 4658dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org bool constantColor, GrPaint* grPaint) { 4668dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org 4678dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org grPaint->setDither(skPaint.isDither()); 4688dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org grPaint->setAntiAlias(skPaint.isAntiAlias()); 4698dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org 4708dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org SkXfermode::Coeff sm; 4718dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org SkXfermode::Coeff dm; 4728dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org 4738dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org SkXfermode* mode = skPaint.getXfermode(); 474b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrFragmentProcessor* xferProcessor = NULL; 475b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt if (SkXfermode::asFragmentProcessorOrCoeff(mode, &xferProcessor, &sm, &dm)) { 476b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt if (xferProcessor) { 477b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt grPaint->addColorProcessor(xferProcessor)->unref(); 4788dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org sm = SkXfermode::kOne_Coeff; 4798dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org dm = SkXfermode::kZero_Coeff; 4808dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org } 4818dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org } else { 4828dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org //SkDEBUGCODE(SkDebugf("Unsupported xfer mode.\n");) 4838dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org // Fall back to src-over 4848dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org sm = SkXfermode::kOne_Coeff; 4858dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org dm = SkXfermode::kISA_Coeff; 4868dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org } 4878dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org grPaint->setBlendFunc(sk_blend_to_grblend(sm), sk_blend_to_grblend(dm)); 4889de5b514d38c5b36066bcdc14fba2f7e5196d372dandov 4899de5b514d38c5b36066bcdc14fba2f7e5196d372dandov //set the color of the paint to the one of the parameter 49083d081ae1d731b5039e99823620f5e287542ee39bsalomon grPaint->setColor(paintColor); 4918dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org 4928dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org SkColorFilter* colorFilter = skPaint.getColorFilter(); 49349f085dddff10473b6ebf832a974288300224e60bsalomon if (colorFilter) { 4948dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org // if the source color is a constant then apply the filter here once rather than per pixel 4958dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org // in a shader. 4968dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org if (constantColor) { 4978dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org SkColor filtered = colorFilter->filterColor(skPaint.getColor()); 4988dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org grPaint->setColor(SkColor2GrColor(filtered)); 4998dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org } else { 500b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt SkAutoTUnref<GrFragmentProcessor> fp(colorFilter->asFragmentProcessor(context)); 501b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt if (fp.get()) { 502b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt grPaint->addColorProcessor(fp); 5038dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org } 5048dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org } 5058dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org } 506f461a8fdf642ba713dcdfb217534652df1eac278krajcevski 507f461a8fdf642ba713dcdfb217534652df1eac278krajcevski#ifndef SK_IGNORE_GPU_DITHER 508f461a8fdf642ba713dcdfb217534652df1eac278krajcevski // If the dither flag is set, then we need to see if the underlying context 509f461a8fdf642ba713dcdfb217534652df1eac278krajcevski // supports it. If not, then install a dither effect. 510f461a8fdf642ba713dcdfb217534652df1eac278krajcevski if (skPaint.isDither() && grPaint->numColorStages() > 0) { 511f461a8fdf642ba713dcdfb217534652df1eac278krajcevski // What are we rendering into? 512f461a8fdf642ba713dcdfb217534652df1eac278krajcevski const GrRenderTarget *target = context->getRenderTarget(); 51349f085dddff10473b6ebf832a974288300224e60bsalomon SkASSERT(target); 514f461a8fdf642ba713dcdfb217534652df1eac278krajcevski 515f461a8fdf642ba713dcdfb217534652df1eac278krajcevski // Suspect the dithering flag has no effect on these configs, otherwise 516f461a8fdf642ba713dcdfb217534652df1eac278krajcevski // fall back on setting the appropriate state. 517f461a8fdf642ba713dcdfb217534652df1eac278krajcevski if (target->config() == kRGBA_8888_GrPixelConfig || 518f461a8fdf642ba713dcdfb217534652df1eac278krajcevski target->config() == kBGRA_8888_GrPixelConfig) { 519f461a8fdf642ba713dcdfb217534652df1eac278krajcevski // The dither flag is set and the target is likely 520f461a8fdf642ba713dcdfb217534652df1eac278krajcevski // not going to be dithered by the GPU. 521b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt SkAutoTUnref<GrFragmentProcessor> fp(GrDitherEffect::Create()); 522b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt if (fp.get()) { 523b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt grPaint->addColorProcessor(fp); 524f461a8fdf642ba713dcdfb217534652df1eac278krajcevski grPaint->setDither(false); 525f461a8fdf642ba713dcdfb217534652df1eac278krajcevski } 526f461a8fdf642ba713dcdfb217534652df1eac278krajcevski } 527f461a8fdf642ba713dcdfb217534652df1eac278krajcevski } 528f461a8fdf642ba713dcdfb217534652df1eac278krajcevski#endif 5298dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org} 5308dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org 5319e967ad6e54c1e2e5ffb9d6e9eb8414e6b36b0e3commit-bot@chromium.org/** 5329e967ad6e54c1e2e5ffb9d6e9eb8414e6b36b0e3commit-bot@chromium.org * Unlike GrContext::AutoMatrix, this doesn't require setting a new matrix. GrContext::AutoMatrix 5339e967ad6e54c1e2e5ffb9d6e9eb8414e6b36b0e3commit-bot@chromium.org * likes to set the new matrix in its constructor because it is usually necessary to simulataneously 5349e967ad6e54c1e2e5ffb9d6e9eb8414e6b36b0e3commit-bot@chromium.org * update a GrPaint. This AutoMatrix is used while initially setting up GrPaint, however. 5359e967ad6e54c1e2e5ffb9d6e9eb8414e6b36b0e3commit-bot@chromium.org */ 5369e967ad6e54c1e2e5ffb9d6e9eb8414e6b36b0e3commit-bot@chromium.orgclass AutoMatrix { 5379e967ad6e54c1e2e5ffb9d6e9eb8414e6b36b0e3commit-bot@chromium.orgpublic: 5389e967ad6e54c1e2e5ffb9d6e9eb8414e6b36b0e3commit-bot@chromium.org AutoMatrix(GrContext* context) { 5399e967ad6e54c1e2e5ffb9d6e9eb8414e6b36b0e3commit-bot@chromium.org fMatrix = context->getMatrix(); 5409e967ad6e54c1e2e5ffb9d6e9eb8414e6b36b0e3commit-bot@chromium.org fContext = context; 5419e967ad6e54c1e2e5ffb9d6e9eb8414e6b36b0e3commit-bot@chromium.org } 5429e967ad6e54c1e2e5ffb9d6e9eb8414e6b36b0e3commit-bot@chromium.org ~AutoMatrix() { 54349f085dddff10473b6ebf832a974288300224e60bsalomon SkASSERT(fContext); 5449e967ad6e54c1e2e5ffb9d6e9eb8414e6b36b0e3commit-bot@chromium.org fContext->setMatrix(fMatrix); 5459e967ad6e54c1e2e5ffb9d6e9eb8414e6b36b0e3commit-bot@chromium.org } 5469e967ad6e54c1e2e5ffb9d6e9eb8414e6b36b0e3commit-bot@chromium.orgprivate: 5479e967ad6e54c1e2e5ffb9d6e9eb8414e6b36b0e3commit-bot@chromium.org GrContext* fContext; 5489e967ad6e54c1e2e5ffb9d6e9eb8414e6b36b0e3commit-bot@chromium.org SkMatrix fMatrix; 5499e967ad6e54c1e2e5ffb9d6e9eb8414e6b36b0e3commit-bot@chromium.org}; 5509e967ad6e54c1e2e5ffb9d6e9eb8414e6b36b0e3commit-bot@chromium.org 5513595f88aff0a1b490aa6661f0ba2d3534ee86353commit-bot@chromium.orgvoid SkPaint2GrPaintShader(GrContext* context, const SkPaint& skPaint, 5528dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org bool constantColor, GrPaint* grPaint) { 5538dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org SkShader* shader = skPaint.getShader(); 5548dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org if (NULL == shader) { 5559de5b514d38c5b36066bcdc14fba2f7e5196d372dandov SkPaint2GrPaintNoShader(context, skPaint, SkColor2GrColor(skPaint.getColor()), 5569de5b514d38c5b36066bcdc14fba2f7e5196d372dandov constantColor, grPaint); 5578dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org return; 5588dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org } 5598dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org 56083d081ae1d731b5039e99823620f5e287542ee39bsalomon GrColor paintColor = SkColor2GrColor(skPaint.getColor()); 561f461a8fdf642ba713dcdfb217534652df1eac278krajcevski 562f461a8fdf642ba713dcdfb217534652df1eac278krajcevski // Start a new block here in order to preserve our context state after calling 563b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt // asFragmentProcessor(). Since these calls get passed back to the client, we don't really 564f461a8fdf642ba713dcdfb217534652df1eac278krajcevski // want them messing around with the context. 565f461a8fdf642ba713dcdfb217534652df1eac278krajcevski { 566b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt // SkShader::asFragmentProcessor() may do offscreen rendering. Save off the current RT, 567b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt // clip, and matrix. We don't reset the matrix on the context because 568b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt // SkShader::asFragmentProcessor may use GrContext::getMatrix() to know the transformation 569b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt // from local coords to device space. 570f461a8fdf642ba713dcdfb217534652df1eac278krajcevski GrContext::AutoRenderTarget art(context, NULL); 571f461a8fdf642ba713dcdfb217534652df1eac278krajcevski GrContext::AutoClip ac(context, GrContext::AutoClip::kWideOpen_InitialClip); 572f461a8fdf642ba713dcdfb217534652df1eac278krajcevski AutoMatrix am(context); 573f461a8fdf642ba713dcdfb217534652df1eac278krajcevski 57483d081ae1d731b5039e99823620f5e287542ee39bsalomon // Allow the shader to modify paintColor and also create an effect to be installed as 57583d081ae1d731b5039e99823620f5e287542ee39bsalomon // the first color effect on the GrPaint. 576b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrFragmentProcessor* fp = NULL; 577b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt if (shader->asFragmentProcessor(context, skPaint, NULL, &paintColor, &fp) && fp) { 578b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt grPaint->addColorProcessor(fp)->unref(); 579f461a8fdf642ba713dcdfb217534652df1eac278krajcevski constantColor = false; 580f461a8fdf642ba713dcdfb217534652df1eac278krajcevski } 5818dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org } 582f461a8fdf642ba713dcdfb217534652df1eac278krajcevski 583b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt // The grcolor is automatically set when calling asFragmentProcessor. 5849de5b514d38c5b36066bcdc14fba2f7e5196d372dandov // If the shader can be seen as an effect it returns true and adds its effect to the grpaint. 58583d081ae1d731b5039e99823620f5e287542ee39bsalomon SkPaint2GrPaintNoShader(context, skPaint, paintColor, constantColor, grPaint); 5868dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org} 587