SkGr.cpp revision 9ed7f573491217079cccf1d81792cf4520a3c0d0
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" 9378092f3d10b1dd62967f419c35cfefec7c10ee7egdaniel 10378092f3d10b1dd62967f419c35cfefec7c10ee7egdaniel#include "GrDrawTargetCaps.h" 11378092f3d10b1dd62967f419c35cfefec7c10ee7egdaniel#include "GrGpu.h" 12378092f3d10b1dd62967f419c35cfefec7c10ee7egdaniel#include "GrXferProcessor.h" 138dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org#include "SkColorFilter.h" 14ea476e1725f38688b79aadf4c5e36c10c3141927commit-bot@chromium.org#include "SkConfig8888.h" 159c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski#include "SkData.h" 1650a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org#include "SkMessageBus.h" 1750a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org#include "SkPixelRef.h" 1840a1e11ebebe81586f3fec96408fdfd4b51123d2krajcevski#include "SkTextureCompressor.h" 19f461a8fdf642ba713dcdfb217534652df1eac278krajcevski#include "effects/GrDitherEffect.h" 20378092f3d10b1dd62967f419c35cfefec7c10ee7egdaniel#include "effects/GrPorterDuffXferProcessor.h" 21518d83dbc1c899e316e8c896af5defb58b83120fsugoi#include "effects/GrYUVtoRGBEffect.h" 229c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski 238c111f783f40470e697310244426362132979ad9krajcevski#ifndef SK_IGNORE_ETC1_SUPPORT 2499ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski# include "ktx.h" 259c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski# include "etc1.h" 269c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski#endif 27ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 28ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com/* Fill out buffer with the compressed format Ganesh expects from a colortable 29ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com based bitmap. [palette (colortable) + indices]. 305782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com 315782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com At the moment Ganesh only supports 8bit version. If Ganesh allowed we others 32ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com we could detect that the colortable.count is <= 16, and then repack the 33ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com indices as nibbles to save RAM, but it would take more time (i.e. a lot 34ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com slower than memcpy), so skipping that for now. 355782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com 36ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com Ganesh wants a full 256 palette entry, even though Skia's ctable is only as big 37ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com as the colortable.count says it is. 38ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com */ 39e79a2dab91a90e26b13bc1ec9b8c6264a1ab22e4bsalomonstatic void build_index8_data(void* buffer, const SkBitmap& bitmap) { 400689d7b12e7c427a077b003d3d8ae759d86f798freed SkASSERT(kIndex_8_SkColorType == bitmap.colorType()); 415782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com 427f4ad5a30ff745e666579d2b518dfd0c1aa49596bsalomon@google.com SkAutoLockPixels alp(bitmap); 43ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com if (!bitmap.readyToDraw()) { 440c00f21fee3f5cfa3aa7e5d46ff94cb8cf340451tomhudson@google.com SkDEBUGFAIL("bitmap not ready to draw!"); 45ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com return; 46ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 47ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 48ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com SkColorTable* ctable = bitmap.getColorTable(); 49ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com char* dst = (char*)buffer; 505782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com 517111d463cee893a479280c7af41757e709e33ef5reed@google.com const int count = ctable->count(); 527111d463cee893a479280c7af41757e709e33ef5reed@google.com 537111d463cee893a479280c7af41757e709e33ef5reed@google.com SkDstPixelInfo dstPI; 547111d463cee893a479280c7af41757e709e33ef5reed@google.com dstPI.fColorType = kRGBA_8888_SkColorType; 557111d463cee893a479280c7af41757e709e33ef5reed@google.com dstPI.fAlphaType = kPremul_SkAlphaType; 567111d463cee893a479280c7af41757e709e33ef5reed@google.com dstPI.fPixels = buffer; 577111d463cee893a479280c7af41757e709e33ef5reed@google.com dstPI.fRowBytes = count * sizeof(SkPMColor); 587111d463cee893a479280c7af41757e709e33ef5reed@google.com 597111d463cee893a479280c7af41757e709e33ef5reed@google.com SkSrcPixelInfo srcPI; 6028fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org srcPI.fColorType = kN32_SkColorType; 617111d463cee893a479280c7af41757e709e33ef5reed@google.com srcPI.fAlphaType = kPremul_SkAlphaType; 62775b8199a214af57c3ea7969e9d456f5f3eb137fmtklein srcPI.fPixels = ctable->readColors(); 637111d463cee893a479280c7af41757e709e33ef5reed@google.com srcPI.fRowBytes = count * sizeof(SkPMColor); 647111d463cee893a479280c7af41757e709e33ef5reed@google.com 657111d463cee893a479280c7af41757e709e33ef5reed@google.com srcPI.convertPixelsTo(&dstPI, count, 1); 667111d463cee893a479280c7af41757e709e33ef5reed@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 108f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomonstatic void generate_bitmap_texture_desc(const SkBitmap& bitmap, GrSurfaceDesc* desc) { 109f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomon desc->fFlags = kNone_GrSurfaceFlags; 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, 142f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomon GrSurfaceDesc 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. 162e30597375c19dfb5197fd065a3d1768401eb00fabsalomon result = ctx->refScratchTexture(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, 173f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomon const SkBitmap &bm, GrSurfaceDesc 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; 209775b8199a214af57c3ea7969e9d456f5f3eb137fmtklein } 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, 222f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomon const SkBitmap& bm, const GrSurfaceDesc& desc) { 223ff58e4679b9473ce19abb81a3e50fc6a18f0981dsugoi // Subsets are not supported, the whole pixelRef is loaded when using YUV decoding 224ff58e4679b9473ce19abb81a3e50fc6a18f0981dsugoi if ((bm.pixelRef()->info().width() != bm.info().width()) || 225ff58e4679b9473ce19abb81a3e50fc6a18f0981dsugoi (bm.pixelRef()->info().height() != bm.info().height())) { 226ff58e4679b9473ce19abb81a3e50fc6a18f0981dsugoi return NULL; 227ff58e4679b9473ce19abb81a3e50fc6a18f0981dsugoi } 228ff58e4679b9473ce19abb81a3e50fc6a18f0981dsugoi 229518d83dbc1c899e316e8c896af5defb58b83120fsugoi SkPixelRef* pixelRef = bm.pixelRef(); 230518d83dbc1c899e316e8c896af5defb58b83120fsugoi SkISize yuvSizes[3]; 231abaef86f2b37d8a939506a2076da07f6db456951rileya if ((NULL == pixelRef) || !pixelRef->getYUV8Planes(yuvSizes, NULL, NULL, NULL)) { 232518d83dbc1c899e316e8c896af5defb58b83120fsugoi return NULL; 233518d83dbc1c899e316e8c896af5defb58b83120fsugoi } 234518d83dbc1c899e316e8c896af5defb58b83120fsugoi 235518d83dbc1c899e316e8c896af5defb58b83120fsugoi // Allocate the memory for YUV 236518d83dbc1c899e316e8c896af5defb58b83120fsugoi size_t totalSize(0); 237518d83dbc1c899e316e8c896af5defb58b83120fsugoi size_t sizes[3], rowBytes[3]; 238518d83dbc1c899e316e8c896af5defb58b83120fsugoi for (int i = 0; i < 3; ++i) { 239518d83dbc1c899e316e8c896af5defb58b83120fsugoi rowBytes[i] = yuvSizes[i].fWidth; 240518d83dbc1c899e316e8c896af5defb58b83120fsugoi totalSize += sizes[i] = rowBytes[i] * yuvSizes[i].fHeight; 241518d83dbc1c899e316e8c896af5defb58b83120fsugoi } 242518d83dbc1c899e316e8c896af5defb58b83120fsugoi SkAutoMalloc storage(totalSize); 243518d83dbc1c899e316e8c896af5defb58b83120fsugoi void* planes[3]; 244518d83dbc1c899e316e8c896af5defb58b83120fsugoi planes[0] = storage.get(); 245518d83dbc1c899e316e8c896af5defb58b83120fsugoi planes[1] = (uint8_t*)planes[0] + sizes[0]; 246518d83dbc1c899e316e8c896af5defb58b83120fsugoi planes[2] = (uint8_t*)planes[1] + sizes[1]; 247518d83dbc1c899e316e8c896af5defb58b83120fsugoi 248abaef86f2b37d8a939506a2076da07f6db456951rileya SkYUVColorSpace colorSpace; 249abaef86f2b37d8a939506a2076da07f6db456951rileya 250518d83dbc1c899e316e8c896af5defb58b83120fsugoi // Get the YUV planes 251abaef86f2b37d8a939506a2076da07f6db456951rileya if (!pixelRef->getYUV8Planes(yuvSizes, planes, rowBytes, &colorSpace)) { 252518d83dbc1c899e316e8c896af5defb58b83120fsugoi return NULL; 253518d83dbc1c899e316e8c896af5defb58b83120fsugoi } 254518d83dbc1c899e316e8c896af5defb58b83120fsugoi 255f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomon GrSurfaceDesc yuvDesc; 256518d83dbc1c899e316e8c896af5defb58b83120fsugoi yuvDesc.fConfig = kAlpha_8_GrPixelConfig; 257e30597375c19dfb5197fd065a3d1768401eb00fabsalomon SkAutoTUnref<GrTexture> yuvTextures[3]; 258518d83dbc1c899e316e8c896af5defb58b83120fsugoi for (int i = 0; i < 3; ++i) { 259518d83dbc1c899e316e8c896af5defb58b83120fsugoi yuvDesc.fWidth = yuvSizes[i].fWidth; 260518d83dbc1c899e316e8c896af5defb58b83120fsugoi yuvDesc.fHeight = yuvSizes[i].fHeight; 261e30597375c19dfb5197fd065a3d1768401eb00fabsalomon yuvTextures[i].reset( 262e30597375c19dfb5197fd065a3d1768401eb00fabsalomon ctx->refScratchTexture(yuvDesc, GrContext::kApprox_ScratchTexMatch)); 263e30597375c19dfb5197fd065a3d1768401eb00fabsalomon if (!yuvTextures[i] || 264e30597375c19dfb5197fd065a3d1768401eb00fabsalomon !yuvTextures[i]->writePixels(0, 0, yuvDesc.fWidth, yuvDesc.fHeight, 265e30597375c19dfb5197fd065a3d1768401eb00fabsalomon yuvDesc.fConfig, planes[i], rowBytes[i])) { 266518d83dbc1c899e316e8c896af5defb58b83120fsugoi return NULL; 267518d83dbc1c899e316e8c896af5defb58b83120fsugoi } 268518d83dbc1c899e316e8c896af5defb58b83120fsugoi } 269518d83dbc1c899e316e8c896af5defb58b83120fsugoi 270f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomon GrSurfaceDesc rtDesc = desc; 271518d83dbc1c899e316e8c896af5defb58b83120fsugoi rtDesc.fFlags = rtDesc.fFlags | 272f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomon kRenderTarget_GrSurfaceFlag | 273f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomon kNoStencil_GrSurfaceFlag; 274518d83dbc1c899e316e8c896af5defb58b83120fsugoi 2750249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi GrTexture* result = sk_gr_allocate_texture(ctx, cache, params, bm, rtDesc, NULL, 0); 276518d83dbc1c899e316e8c896af5defb58b83120fsugoi 277518d83dbc1c899e316e8c896af5defb58b83120fsugoi GrRenderTarget* renderTarget = result ? result->asRenderTarget() : NULL; 27849f085dddff10473b6ebf832a974288300224e60bsalomon if (renderTarget) { 279e30597375c19dfb5197fd065a3d1768401eb00fabsalomon SkAutoTUnref<GrFragmentProcessor> yuvToRgbProcessor( 280e30597375c19dfb5197fd065a3d1768401eb00fabsalomon GrYUVtoRGBEffect::Create(yuvTextures[0], yuvTextures[1], yuvTextures[2], colorSpace)); 281518d83dbc1c899e316e8c896af5defb58b83120fsugoi GrPaint paint; 282b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt paint.addColorProcessor(yuvToRgbProcessor); 283518d83dbc1c899e316e8c896af5defb58b83120fsugoi SkRect r = SkRect::MakeWH(SkIntToScalar(yuvSizes[0].fWidth), 284518d83dbc1c899e316e8c896af5defb58b83120fsugoi SkIntToScalar(yuvSizes[0].fHeight)); 285518d83dbc1c899e316e8c896af5defb58b83120fsugoi GrContext::AutoRenderTarget autoRT(ctx, renderTarget); 286518d83dbc1c899e316e8c896af5defb58b83120fsugoi GrContext::AutoClip ac(ctx, GrContext::AutoClip::kWideOpen_InitialClip); 2875531d51ce7426bdae7563547326fcf0bf926a083joshualitt ctx->drawRect(paint, SkMatrix::I(), r); 288518d83dbc1c899e316e8c896af5defb58b83120fsugoi } else { 289518d83dbc1c899e316e8c896af5defb58b83120fsugoi SkSafeSetNull(result); 290518d83dbc1c899e316e8c896af5defb58b83120fsugoi } 291518d83dbc1c899e316e8c896af5defb58b83120fsugoi 292518d83dbc1c899e316e8c896af5defb58b83120fsugoi return result; 293518d83dbc1c899e316e8c896af5defb58b83120fsugoi} 294518d83dbc1c899e316e8c896af5defb58b83120fsugoi 2951f47f4f7325971dd53991e2bb02da94fa7c6d962robertphillips@google.comstatic GrTexture* sk_gr_create_bitmap_texture(GrContext* ctx, 2960797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com bool cache, 2971f47f4f7325971dd53991e2bb02da94fa7c6d962robertphillips@google.com const GrTextureParams* params, 2981f47f4f7325971dd53991e2bb02da94fa7c6d962robertphillips@google.com const SkBitmap& origBitmap) { 299ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com SkBitmap tmpBitmap; 300ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 301ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com const SkBitmap* bitmap = &origBitmap; 3025782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com 303f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomon GrSurfaceDesc desc; 3040797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com generate_bitmap_texture_desc(*bitmap, &desc); 3055782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com 3060689d7b12e7c427a077b003d3d8ae759d86f798freed if (kIndex_8_SkColorType == bitmap->colorType()) { 307ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com // build_compressed_data doesn't do npot->pot expansion 308ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com // and paletted textures can't be sub-updated 309e79a2dab91a90e26b13bc1ec9b8c6264a1ab22e4bsalomon if (cache && ctx->supportsIndex8PixelConfig(params, bitmap->width(), bitmap->height())) { 310d4cb922ea1a85d381e88975b63664f6c0bf28cdbbsalomon size_t imageSize = GrCompressedFormatDataSize(kIndex_8_GrPixelConfig, 311d4cb922ea1a85d381e88975b63664f6c0bf28cdbbsalomon bitmap->width(), bitmap->height()); 312d4cb922ea1a85d381e88975b63664f6c0bf28cdbbsalomon SkAutoMalloc storage(imageSize); 313e79a2dab91a90e26b13bc1ec9b8c6264a1ab22e4bsalomon build_index8_data(storage.get(), origBitmap); 314ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 315ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com // our compressed data will be trimmed, so pass width() for its 316ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com // "rowBytes", since they are the same now. 3170249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi return sk_gr_allocate_texture(ctx, cache, params, origBitmap, 3180249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi desc, storage.get(), bitmap->width()); 319ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } else { 32028fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org origBitmap.copyTo(&tmpBitmap, kN32_SkColorType); 321ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com // now bitmap points to our temp, which has been promoted to 32bits 322ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com bitmap = &tmpBitmap; 3233adcc3403377c0b9a7afde6db8e0432325413a10commit-bot@chromium.org desc.fConfig = SkImageInfo2GrPixelConfig(bitmap->info()); 324ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 325309e86912445879651d52ebbedb67b4ff3f1516ckrajcevski } 3269c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski 3279c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski // Is this an ETC1 encoded texture? 3288c111f783f40470e697310244426362132979ad9krajcevski#ifndef SK_IGNORE_ETC1_SUPPORT 3299a3cdbb3d0957ad3f04d02277a4ce839752f4efdkrajcevski else if ( 33077cd8b0ba20bca3a9d994586eb58337bcf2082fbbungeman // We do not support scratch ETC1 textures, hence they should all be at least 33177cd8b0ba20bca3a9d994586eb58337bcf2082fbbungeman // trying to go to the cache. 33277cd8b0ba20bca3a9d994586eb58337bcf2082fbbungeman cache 3339a3cdbb3d0957ad3f04d02277a4ce839752f4efdkrajcevski // Make sure that the underlying device supports ETC1 textures before we go ahead 3349a3cdbb3d0957ad3f04d02277a4ce839752f4efdkrajcevski // and check the data. 33577cd8b0ba20bca3a9d994586eb58337bcf2082fbbungeman && ctx->getGpu()->caps()->isConfigTexturable(kETC1_GrPixelConfig) 3369a3cdbb3d0957ad3f04d02277a4ce839752f4efdkrajcevski // If the bitmap had compressed data and was then uncompressed, it'll still return 3379a3cdbb3d0957ad3f04d02277a4ce839752f4efdkrajcevski // compressed data on 'refEncodedData' and upload it. Probably not good, since if 3389a3cdbb3d0957ad3f04d02277a4ce839752f4efdkrajcevski // the bitmap has available pixels, then they might not be what the decompressed 3399a3cdbb3d0957ad3f04d02277a4ce839752f4efdkrajcevski // data is. 3409a3cdbb3d0957ad3f04d02277a4ce839752f4efdkrajcevski && !(bitmap->readyToDraw())) { 3410249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi GrTexture *texture = load_etc1_texture(ctx, cache, params, *bitmap, desc); 34249f085dddff10473b6ebf832a974288300224e60bsalomon if (texture) { 3439c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski return texture; 3449c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski } 3455782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com } 3468c111f783f40470e697310244426362132979ad9krajcevski#endif // SK_IGNORE_ETC1_SUPPORT 347ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 348518d83dbc1c899e316e8c896af5defb58b83120fsugoi else { 3490249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi GrTexture *texture = load_yuv_texture(ctx, cache, params, *bitmap, desc); 35049f085dddff10473b6ebf832a974288300224e60bsalomon if (texture) { 351518d83dbc1c899e316e8c896af5defb58b83120fsugoi return texture; 352518d83dbc1c899e316e8c896af5defb58b83120fsugoi } 353518d83dbc1c899e316e8c896af5defb58b83120fsugoi } 3547f4ad5a30ff745e666579d2b518dfd0c1aa49596bsalomon@google.com SkAutoLockPixels alp(*bitmap); 3557f4ad5a30ff745e666579d2b518dfd0c1aa49596bsalomon@google.com if (!bitmap->readyToDraw()) { 3567f4ad5a30ff745e666579d2b518dfd0c1aa49596bsalomon@google.com return NULL; 3577f4ad5a30ff745e666579d2b518dfd0c1aa49596bsalomon@google.com } 35850a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org 3590249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi return sk_gr_allocate_texture(ctx, cache, params, origBitmap, desc, 3600249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi bitmap->getPixels(), bitmap->rowBytes()); 361ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 362ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 3639ed7f573491217079cccf1d81792cf4520a3c0d0bsalomonstatic GrTexture* get_texture_backing_bmp(const SkBitmap& bitmap, const GrContext* context, 3649ed7f573491217079cccf1d81792cf4520a3c0d0bsalomon const GrTextureParams* params) { 3659ed7f573491217079cccf1d81792cf4520a3c0d0bsalomon if (GrTexture* texture = bitmap.getTexture()) { 3669ed7f573491217079cccf1d81792cf4520a3c0d0bsalomon // Our texture-resizing-for-tiling used to upscale NPOT textures for tiling only works with 3679ed7f573491217079cccf1d81792cf4520a3c0d0bsalomon // content-key cached resources. Rather than invest in that legacy code path, we'll just 3689ed7f573491217079cccf1d81792cf4520a3c0d0bsalomon // take the horribly slow route of causing a cache miss which will cause the pixels to be 3699ed7f573491217079cccf1d81792cf4520a3c0d0bsalomon // read and reuploaded to a texture with a content key. 3709ed7f573491217079cccf1d81792cf4520a3c0d0bsalomon if (params && !context->getGpu()->caps()->npotTextureTileSupport() && 3719ed7f573491217079cccf1d81792cf4520a3c0d0bsalomon (params->isTiled() || GrTextureParams::kMipMap_FilterMode == params->filterMode())) { 3729ed7f573491217079cccf1d81792cf4520a3c0d0bsalomon return NULL; 3739ed7f573491217079cccf1d81792cf4520a3c0d0bsalomon } 3749ed7f573491217079cccf1d81792cf4520a3c0d0bsalomon return texture; 3759ed7f573491217079cccf1d81792cf4520a3c0d0bsalomon } 3769ed7f573491217079cccf1d81792cf4520a3c0d0bsalomon return NULL; 3779ed7f573491217079cccf1d81792cf4520a3c0d0bsalomon} 3789ed7f573491217079cccf1d81792cf4520a3c0d0bsalomon 3790797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.combool GrIsBitmapInCache(const GrContext* ctx, 3800797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com const SkBitmap& bitmap, 3810797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com const GrTextureParams* params) { 3829ed7f573491217079cccf1d81792cf4520a3c0d0bsalomon if (get_texture_backing_bmp(bitmap, ctx, params)) { 3839ed7f573491217079cccf1d81792cf4520a3c0d0bsalomon return true; 3849ed7f573491217079cccf1d81792cf4520a3c0d0bsalomon } 3859ed7f573491217079cccf1d81792cf4520a3c0d0bsalomon 3860797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com GrCacheID cacheID; 3870797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com generate_bitmap_cache_id(bitmap, &cacheID); 3880797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com 389f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomon GrSurfaceDesc desc; 3900797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com generate_bitmap_texture_desc(bitmap, &desc); 3910797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com return ctx->isTextureInCache(desc, cacheID, params); 3920797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com} 393ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 394bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomonGrTexture* GrRefCachedBitmapTexture(GrContext* ctx, 395bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon const SkBitmap& bitmap, 396bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon const GrTextureParams* params) { 3979ed7f573491217079cccf1d81792cf4520a3c0d0bsalomon GrTexture* result = get_texture_backing_bmp(bitmap, ctx, params); 3989ed7f573491217079cccf1d81792cf4520a3c0d0bsalomon if (result) { 3999ed7f573491217079cccf1d81792cf4520a3c0d0bsalomon return SkRef(result); 4009ed7f573491217079cccf1d81792cf4520a3c0d0bsalomon } 40124f3ad1bbb44916cae33f5d3cf2a20af4bbc381frileya@google.com 4020797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com bool cache = !bitmap.isVolatile(); 4039c2ea846351a29208cb4a36301ee611e7fb384earobertphillips@google.com 4040797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com if (cache) { 4050797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com // If the bitmap isn't changing try to find a cached copy first. 4064b86e3428b115202e82d49a0914ea8ab6dc25940bsalomon@google.com 4070797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com GrCacheID cacheID; 4080797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com generate_bitmap_cache_id(bitmap, &cacheID); 4090b6ad2297fbf43466950690102c1c9c150f2a972bsalomon@google.com 410f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomon GrSurfaceDesc desc; 4110797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com generate_bitmap_texture_desc(bitmap, &desc); 4120797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com 41395ed55adc6b8f0cee063c2cf2e14782773b0087fbsalomon@google.com result = ctx->findAndRefTexture(desc, cacheID, params); 4140797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com } 4150797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com if (NULL == result) { 4160797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com result = sk_gr_create_bitmap_texture(ctx, cache, params, bitmap); 41724f3ad1bbb44916cae33f5d3cf2a20af4bbc381frileya@google.com } 4181f47f4f7325971dd53991e2bb02da94fa7c6d962robertphillips@google.com if (NULL == result) { 41938406c82b913350e55fa04af8c1941cd9b4aff52tfarina SkDebugf("---- failed to create texture for cache [%d %d]\n", 42038406c82b913350e55fa04af8c1941cd9b4aff52tfarina bitmap.width(), bitmap.height()); 42124f3ad1bbb44916cae33f5d3cf2a20af4bbc381frileya@google.com } 4221f47f4f7325971dd53991e2bb02da94fa7c6d962robertphillips@google.com return result; 42324f3ad1bbb44916cae33f5d3cf2a20af4bbc381frileya@google.com} 42424f3ad1bbb44916cae33f5d3cf2a20af4bbc381frileya@google.com 42524f3ad1bbb44916cae33f5d3cf2a20af4bbc381frileya@google.com/////////////////////////////////////////////////////////////////////////////// 42624f3ad1bbb44916cae33f5d3cf2a20af4bbc381frileya@google.com 42715a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org// alphatype is ignore for now, but if GrPixelConfig is expanded to encompass 42815a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org// alpha info, that will be considered. 42915a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.orgGrPixelConfig SkImageInfo2GrPixelConfig(SkColorType ct, SkAlphaType) { 43015a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org switch (ct) { 43115a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org case kUnknown_SkColorType: 43215a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org return kUnknown_GrPixelConfig; 43315a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org case kAlpha_8_SkColorType: 43415a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org return kAlpha_8_GrPixelConfig; 43515a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org case kRGB_565_SkColorType: 43615a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org return kRGB_565_GrPixelConfig; 43715a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org case kARGB_4444_SkColorType: 43815a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org return kRGBA_4444_GrPixelConfig; 43915a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org case kRGBA_8888_SkColorType: 44015a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org return kRGBA_8888_GrPixelConfig; 44115a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org case kBGRA_8888_SkColorType: 44215a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org return kBGRA_8888_GrPixelConfig; 44315a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org case kIndex_8_SkColorType: 44415a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org return kIndex_8_GrPixelConfig; 44515a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org } 44615a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org SkASSERT(0); // shouldn't get here 44715a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org return kUnknown_GrPixelConfig; 44815a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org} 44915a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org 450bf790232f6d94b54239dbc210d8beee7411ca458reed@google.combool GrPixelConfig2ColorType(GrPixelConfig config, SkColorType* ctOut) { 451bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com SkColorType ct; 452bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com switch (config) { 453bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com case kAlpha_8_GrPixelConfig: 454bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com ct = kAlpha_8_SkColorType; 455bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com break; 456bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com case kIndex_8_GrPixelConfig: 457bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com ct = kIndex_8_SkColorType; 458bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com break; 459bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com case kRGB_565_GrPixelConfig: 460bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com ct = kRGB_565_SkColorType; 461bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com break; 462bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com case kRGBA_4444_GrPixelConfig: 463bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com ct = kARGB_4444_SkColorType; 464bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com break; 465bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com case kRGBA_8888_GrPixelConfig: 466bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com ct = kRGBA_8888_SkColorType; 467bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com break; 468bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com case kBGRA_8888_GrPixelConfig: 469bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com ct = kBGRA_8888_SkColorType; 470bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com break; 471bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com default: 472bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com return false; 473bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com } 474bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com if (ctOut) { 475bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com *ctOut = ct; 476bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com } 477bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com return true; 478bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com} 4798dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org 4808dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 4818dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org 48283d081ae1d731b5039e99823620f5e287542ee39bsalomonvoid SkPaint2GrPaintNoShader(GrContext* context, const SkPaint& skPaint, GrColor paintColor, 4838dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org bool constantColor, GrPaint* grPaint) { 4848dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org 4858dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org grPaint->setDither(skPaint.isDither()); 4868dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org grPaint->setAntiAlias(skPaint.isAntiAlias()); 4878dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org 4888dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org SkXfermode* mode = skPaint.getXfermode(); 489378092f3d10b1dd62967f419c35cfefec7c10ee7egdaniel GrFragmentProcessor* fragmentProcessor = NULL; 490378092f3d10b1dd62967f419c35cfefec7c10ee7egdaniel GrXPFactory* xpFactory = NULL; 4919513143efa734bef0c1a0c7f945022572dbc8518egdaniel if (SkXfermode::AsFragmentProcessorOrXPFactory(mode, &fragmentProcessor, &xpFactory)) { 492378092f3d10b1dd62967f419c35cfefec7c10ee7egdaniel if (fragmentProcessor) { 493378092f3d10b1dd62967f419c35cfefec7c10ee7egdaniel SkASSERT(NULL == xpFactory); 494378092f3d10b1dd62967f419c35cfefec7c10ee7egdaniel grPaint->addColorProcessor(fragmentProcessor)->unref(); 495c016fb8f9fb53dd8d4936c5e9e16a9dc99ab392eegdaniel xpFactory = GrPorterDuffXPFactory::Create(SkXfermode::kSrc_Mode); 4968dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org } 4978dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org } else { 4988dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org // Fall back to src-over 499c016fb8f9fb53dd8d4936c5e9e16a9dc99ab392eegdaniel xpFactory = GrPorterDuffXPFactory::Create(SkXfermode::kSrcOver_Mode); 5008dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org } 501378092f3d10b1dd62967f419c35cfefec7c10ee7egdaniel SkASSERT(xpFactory); 502378092f3d10b1dd62967f419c35cfefec7c10ee7egdaniel grPaint->setXPFactory(xpFactory)->unref(); 503775b8199a214af57c3ea7969e9d456f5f3eb137fmtklein 5049de5b514d38c5b36066bcdc14fba2f7e5196d372dandov //set the color of the paint to the one of the parameter 50583d081ae1d731b5039e99823620f5e287542ee39bsalomon grPaint->setColor(paintColor); 5068dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org 5078dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org SkColorFilter* colorFilter = skPaint.getColorFilter(); 50849f085dddff10473b6ebf832a974288300224e60bsalomon if (colorFilter) { 5098dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org // if the source color is a constant then apply the filter here once rather than per pixel 5108dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org // in a shader. 5118dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org if (constantColor) { 5128dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org SkColor filtered = colorFilter->filterColor(skPaint.getColor()); 5138dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org grPaint->setColor(SkColor2GrColor(filtered)); 5148dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org } else { 515b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt SkAutoTUnref<GrFragmentProcessor> fp(colorFilter->asFragmentProcessor(context)); 516b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt if (fp.get()) { 517b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt grPaint->addColorProcessor(fp); 5188dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org } 5198dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org } 5208dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org } 521f461a8fdf642ba713dcdfb217534652df1eac278krajcevski 522f461a8fdf642ba713dcdfb217534652df1eac278krajcevski#ifndef SK_IGNORE_GPU_DITHER 523f461a8fdf642ba713dcdfb217534652df1eac278krajcevski // If the dither flag is set, then we need to see if the underlying context 524f461a8fdf642ba713dcdfb217534652df1eac278krajcevski // supports it. If not, then install a dither effect. 525f461a8fdf642ba713dcdfb217534652df1eac278krajcevski if (skPaint.isDither() && grPaint->numColorStages() > 0) { 526f461a8fdf642ba713dcdfb217534652df1eac278krajcevski // What are we rendering into? 527f461a8fdf642ba713dcdfb217534652df1eac278krajcevski const GrRenderTarget *target = context->getRenderTarget(); 52849f085dddff10473b6ebf832a974288300224e60bsalomon SkASSERT(target); 529f461a8fdf642ba713dcdfb217534652df1eac278krajcevski 530f461a8fdf642ba713dcdfb217534652df1eac278krajcevski // Suspect the dithering flag has no effect on these configs, otherwise 531f461a8fdf642ba713dcdfb217534652df1eac278krajcevski // fall back on setting the appropriate state. 532f461a8fdf642ba713dcdfb217534652df1eac278krajcevski if (target->config() == kRGBA_8888_GrPixelConfig || 533f461a8fdf642ba713dcdfb217534652df1eac278krajcevski target->config() == kBGRA_8888_GrPixelConfig) { 534f461a8fdf642ba713dcdfb217534652df1eac278krajcevski // The dither flag is set and the target is likely 535f461a8fdf642ba713dcdfb217534652df1eac278krajcevski // not going to be dithered by the GPU. 536b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt SkAutoTUnref<GrFragmentProcessor> fp(GrDitherEffect::Create()); 537b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt if (fp.get()) { 538b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt grPaint->addColorProcessor(fp); 539f461a8fdf642ba713dcdfb217534652df1eac278krajcevski grPaint->setDither(false); 540f461a8fdf642ba713dcdfb217534652df1eac278krajcevski } 541f461a8fdf642ba713dcdfb217534652df1eac278krajcevski } 542f461a8fdf642ba713dcdfb217534652df1eac278krajcevski } 543f461a8fdf642ba713dcdfb217534652df1eac278krajcevski#endif 5448dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org} 5458dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org 5465531d51ce7426bdae7563547326fcf0bf926a083joshualittvoid SkPaint2GrPaintShader(GrContext* context, const SkPaint& skPaint, const SkMatrix& viewM, 5478dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org bool constantColor, GrPaint* grPaint) { 5488dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org SkShader* shader = skPaint.getShader(); 5498dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org if (NULL == shader) { 5509de5b514d38c5b36066bcdc14fba2f7e5196d372dandov SkPaint2GrPaintNoShader(context, skPaint, SkColor2GrColor(skPaint.getColor()), 5519de5b514d38c5b36066bcdc14fba2f7e5196d372dandov constantColor, grPaint); 5528dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org return; 5538dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org } 5548dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org 55583d081ae1d731b5039e99823620f5e287542ee39bsalomon GrColor paintColor = SkColor2GrColor(skPaint.getColor()); 556f461a8fdf642ba713dcdfb217534652df1eac278krajcevski 557f461a8fdf642ba713dcdfb217534652df1eac278krajcevski // Start a new block here in order to preserve our context state after calling 558b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt // asFragmentProcessor(). Since these calls get passed back to the client, we don't really 559f461a8fdf642ba713dcdfb217534652df1eac278krajcevski // want them messing around with the context. 560f461a8fdf642ba713dcdfb217534652df1eac278krajcevski { 561b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt // SkShader::asFragmentProcessor() may do offscreen rendering. Save off the current RT, 5625531d51ce7426bdae7563547326fcf0bf926a083joshualitt // and clip 563f461a8fdf642ba713dcdfb217534652df1eac278krajcevski GrContext::AutoRenderTarget art(context, NULL); 564f461a8fdf642ba713dcdfb217534652df1eac278krajcevski GrContext::AutoClip ac(context, GrContext::AutoClip::kWideOpen_InitialClip); 565f461a8fdf642ba713dcdfb217534652df1eac278krajcevski 56683d081ae1d731b5039e99823620f5e287542ee39bsalomon // Allow the shader to modify paintColor and also create an effect to be installed as 56783d081ae1d731b5039e99823620f5e287542ee39bsalomon // the first color effect on the GrPaint. 568b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrFragmentProcessor* fp = NULL; 5695531d51ce7426bdae7563547326fcf0bf926a083joshualitt if (shader->asFragmentProcessor(context, skPaint, viewM, NULL, &paintColor, &fp) && fp) { 570b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt grPaint->addColorProcessor(fp)->unref(); 571f461a8fdf642ba713dcdfb217534652df1eac278krajcevski constantColor = false; 572f461a8fdf642ba713dcdfb217534652df1eac278krajcevski } 5738dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org } 574f461a8fdf642ba713dcdfb217534652df1eac278krajcevski 575b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt // The grcolor is automatically set when calling asFragmentProcessor. 5769de5b514d38c5b36066bcdc14fba2f7e5196d372dandov // If the shader can be seen as an effect it returns true and adds its effect to the grpaint. 57783d081ae1d731b5039e99823620f5e287542ee39bsalomon SkPaint2GrPaintNoShader(context, skPaint, paintColor, constantColor, grPaint); 5788dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org} 579