SkGr.cpp revision 23e619cf462b2a8a500f3ca750e099f79601f508
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 "GrXferProcessor.h" 118dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org#include "SkColorFilter.h" 12ea476e1725f38688b79aadf4c5e36c10c3141927commit-bot@chromium.org#include "SkConfig8888.h" 139c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski#include "SkData.h" 1450a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org#include "SkMessageBus.h" 1550a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org#include "SkPixelRef.h" 16692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi#include "SkResourceCache.h" 1740a1e11ebebe81586f3fec96408fdfd4b51123d2krajcevski#include "SkTextureCompressor.h" 18692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi#include "SkYUVPlanesCache.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 8737f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomonenum Stretch { 8837f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon kNo_Stretch, 8937f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon kBilerp_Stretch, 9037f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon kNearest_Stretch 9137f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon}; 9237f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon 9337f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomonstatic Stretch get_stretch_type(const GrContext* ctx, int width, int height, 9437f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon const GrTextureParams* params) { 9537f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon if (params && params->isTiled()) { 96d2a6f4e419393d3c8d8fe332f11c4c6f88382e1dbsalomon if (!ctx->npotTextureTileSupport() && (!SkIsPow2(width) || !SkIsPow2(height))) { 9737f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon switch(params->filterMode()) { 9837f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon case GrTextureParams::kNone_FilterMode: 9937f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon return kNearest_Stretch; 10037f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon case GrTextureParams::kBilerp_FilterMode: 10137f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon case GrTextureParams::kMipMap_FilterMode: 10237f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon return kBilerp_Stretch; 10337f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon } 10437f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon } 10537f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon } 10637f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon return kNo_Stretch; 10737f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon} 10837f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon 10923e619cf462b2a8a500f3ca750e099f79601f508bsalomonstatic bool make_stretched_key(const GrContentKey& origKey, Stretch stretch, 11023e619cf462b2a8a500f3ca750e099f79601f508bsalomon GrContentKey* stretchedKey) { 11137f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon if (origKey.isValid() && kNo_Stretch != stretch) { 11237f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon static const GrContentKey::Domain kDomain = GrContentKey::GenerateDomain(); 11323e619cf462b2a8a500f3ca750e099f79601f508bsalomon GrContentKey::Builder builder(stretchedKey, origKey, kDomain, 1); 11437f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon builder[0] = stretch; 11537f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon builder.finish(); 11637f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon return true; 11737f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon } 11823e619cf462b2a8a500f3ca750e099f79601f508bsalomon SkASSERT(!stretchedKey->isValid()); 11937f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon return false; 12037f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon} 12137f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon 12223e619cf462b2a8a500f3ca750e099f79601f508bsalomonstatic void make_unstretched_key(const SkBitmap& bitmap, GrContentKey* key) { 1230797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com // Our id includes the offset, width, and height so that bitmaps created by extractSubset() 1240797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com // are unique. 1250797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com uint32_t genID = bitmap.getGenerationID(); 126672588b684d484dce6ae251e9e163e4a46924322reed@google.com SkIPoint origin = bitmap.pixelRefOrigin(); 12724db3b1c35fb935660229da164fc5ad31977387fbsalomon uint32_t width = SkToU16(bitmap.width()); 12824db3b1c35fb935660229da164fc5ad31977387fbsalomon uint32_t height = SkToU16(bitmap.height()); 12924db3b1c35fb935660229da164fc5ad31977387fbsalomon 13024db3b1c35fb935660229da164fc5ad31977387fbsalomon static const GrContentKey::Domain kDomain = GrContentKey::GenerateDomain(); 13124db3b1c35fb935660229da164fc5ad31977387fbsalomon GrContentKey::Builder builder(key, kDomain, 4); 13224db3b1c35fb935660229da164fc5ad31977387fbsalomon builder[0] = genID; 13324db3b1c35fb935660229da164fc5ad31977387fbsalomon builder[1] = origin.fX; 13424db3b1c35fb935660229da164fc5ad31977387fbsalomon builder[2] = origin.fY; 13524db3b1c35fb935660229da164fc5ad31977387fbsalomon builder[3] = width | (height << 16); 13623e619cf462b2a8a500f3ca750e099f79601f508bsalomon} 13737f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon 13823e619cf462b2a8a500f3ca750e099f79601f508bsalomonstatic void make_bitmap_keys(const SkBitmap& bitmap, 13923e619cf462b2a8a500f3ca750e099f79601f508bsalomon Stretch stretch, 14023e619cf462b2a8a500f3ca750e099f79601f508bsalomon GrContentKey* key, 14123e619cf462b2a8a500f3ca750e099f79601f508bsalomon GrContentKey* stretchedKey) { 14223e619cf462b2a8a500f3ca750e099f79601f508bsalomon make_unstretched_key(bitmap, key); 14337f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon if (kNo_Stretch != stretch) { 14423e619cf462b2a8a500f3ca750e099f79601f508bsalomon make_stretched_key(*key, stretch, stretchedKey); 14537f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon } 1460797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com} 1470797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com 148f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomonstatic void generate_bitmap_texture_desc(const SkBitmap& bitmap, GrSurfaceDesc* desc) { 149f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomon desc->fFlags = kNone_GrSurfaceFlags; 1500797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com desc->fWidth = bitmap.width(); 1510797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com desc->fHeight = bitmap.height(); 1523adcc3403377c0b9a7afde6db8e0432325413a10commit-bot@chromium.org desc->fConfig = SkImageInfo2GrPixelConfig(bitmap.info()); 1530797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com desc->fSampleCnt = 0; 1540797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com} 1550797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com 15650a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.orgnamespace { 15750a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org 15850a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org// When the SkPixelRef genID changes, invalidate a corresponding GrResource described by key. 15923e619cf462b2a8a500f3ca750e099f79601f508bsalomonclass BitmapInvalidator : public SkPixelRef::GenIDChangeListener { 16050a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.orgpublic: 16123e619cf462b2a8a500f3ca750e099f79601f508bsalomon explicit BitmapInvalidator(const GrContentKey& key) : fMsg(key) {} 16250a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.orgprivate: 16323e619cf462b2a8a500f3ca750e099f79601f508bsalomon GrContentKeyInvalidatedMessage fMsg; 16450a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org 16572c9faab45124e08c85f70ca38536914862d947cmtklein void onChange() SK_OVERRIDE { 16623e619cf462b2a8a500f3ca750e099f79601f508bsalomon SkMessageBus<GrContentKeyInvalidatedMessage>::Post(fMsg); 16750a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org } 16850a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org}; 16950a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org 17050a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org} // namespace 17150a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org 17250a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org 17337f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomonstatic GrTexture* create_texture_for_bmp(GrContext* ctx, 17437f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon const GrContentKey& optionalKey, 175f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomon GrSurfaceDesc desc, 17623e619cf462b2a8a500f3ca750e099f79601f508bsalomon SkPixelRef* pixelRefForInvalidationNotification, 1770249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi const void* pixels, 1780249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi size_t rowBytes) { 179d0423587ac56ae84d3f1eb796d5c1e2dfba9646ebsalomon GrTexture* result = ctx->createTexture(desc, true, pixels, rowBytes); 180d0423587ac56ae84d3f1eb796d5c1e2dfba9646ebsalomon if (result && optionalKey.isValid()) { 18123e619cf462b2a8a500f3ca750e099f79601f508bsalomon BitmapInvalidator* listener = SkNEW_ARGS(BitmapInvalidator, (optionalKey)); 18223e619cf462b2a8a500f3ca750e099f79601f508bsalomon pixelRefForInvalidationNotification->addGenIDChangeListener(listener); 183d0423587ac56ae84d3f1eb796d5c1e2dfba9646ebsalomon SkAssertResult(ctx->addResourceToCache(optionalKey, result)); 1840249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi } 1850249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi return result; 1860249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi} 1870249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi 18837f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon// creates a new texture that is the input texture scaled up to the next power of two in 18937f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon// width or height. If optionalKey is valid it will be set on the new texture. stretch 19037f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon// controls whether the scaling is done using nearest or bilerp filtering. 19123e619cf462b2a8a500f3ca750e099f79601f508bsalomonGrTexture* stretch_texture_to_next_pot(GrTexture* inputTexture, Stretch stretch, 19223e619cf462b2a8a500f3ca750e099f79601f508bsalomon SkPixelRef* pixelRef, 19323e619cf462b2a8a500f3ca750e099f79601f508bsalomon const GrContentKey& optionalKey) { 19437f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon SkASSERT(kNo_Stretch != stretch); 19537f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon 19637f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon GrContext* context = inputTexture->getContext(); 19737f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon SkASSERT(context); 19837f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon 19937f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon // Either it's a cache miss or the original wasn't cached to begin with. 20037f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon GrSurfaceDesc rtDesc = inputTexture->desc(); 20137f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon rtDesc.fFlags = rtDesc.fFlags | 20237f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon kRenderTarget_GrSurfaceFlag | 20337f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon kNoStencil_GrSurfaceFlag; 20437f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon rtDesc.fWidth = GrNextPow2(rtDesc.fWidth); 20537f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon rtDesc.fHeight = GrNextPow2(rtDesc.fHeight); 20637f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon rtDesc.fConfig = GrMakePixelConfigUncompressed(rtDesc.fConfig); 20737f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon 20837f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon // If the config isn't renderable try converting to either A8 or an 32 bit config. Otherwise, 20937f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon // fail. 21037f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon if (!context->isConfigRenderable(rtDesc.fConfig, false)) { 21137f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon if (GrPixelConfigIsAlphaOnly(rtDesc.fConfig)) { 21237f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon if (context->isConfigRenderable(kAlpha_8_GrPixelConfig, false)) { 21337f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon rtDesc.fConfig = kAlpha_8_GrPixelConfig; 21437f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon } else if (context->isConfigRenderable(kSkia8888_GrPixelConfig, false)) { 21537f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon rtDesc.fConfig = kSkia8888_GrPixelConfig; 21637f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon } else { 21737f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon return NULL; 21837f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon } 21937f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon } else if (kRGB_GrColorComponentFlags == 22037f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon (kRGB_GrColorComponentFlags & GrPixelConfigComponentMask(rtDesc.fConfig))) { 22137f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon if (context->isConfigRenderable(kSkia8888_GrPixelConfig, false)) { 22237f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon rtDesc.fConfig = kSkia8888_GrPixelConfig; 22337f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon } else { 22437f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon return NULL; 22537f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon } 22637f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon } else { 22737f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon return NULL; 22837f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon } 22937f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon } 23037f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon 23123e619cf462b2a8a500f3ca750e099f79601f508bsalomon GrTexture* stretched = create_texture_for_bmp(context, optionalKey, rtDesc, pixelRef, NULL, 0); 23237f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon 23323e619cf462b2a8a500f3ca750e099f79601f508bsalomon if (!stretched) { 23437f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon return NULL; 23537f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon } 23637f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon GrPaint paint; 23737f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon 23837f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon // If filtering is not desired then we want to ensure all texels in the resampled image are 23937f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon // copies of texels from the original. 24037f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon GrTextureParams params(SkShader::kClamp_TileMode, 24137f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon kBilerp_Stretch == stretch ? GrTextureParams::kBilerp_FilterMode : 24237f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon GrTextureParams::kNone_FilterMode); 24337f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon paint.addColorTextureProcessor(inputTexture, SkMatrix::I(), params); 24437f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon 24537f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon SkRect rect = SkRect::MakeWH(SkIntToScalar(rtDesc.fWidth), SkIntToScalar(rtDesc.fHeight)); 24637f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon SkRect localRect = SkRect::MakeWH(1.f, 1.f); 24737f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon 24823e619cf462b2a8a500f3ca750e099f79601f508bsalomon GrContext::AutoRenderTarget autoRT(context, stretched->asRenderTarget()); 24937f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon GrContext::AutoClip ac(context, GrContext::AutoClip::kWideOpen_InitialClip); 25037f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon context->drawNonAARectToRect(paint, SkMatrix::I(), rect, localRect); 25137f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon 25223e619cf462b2a8a500f3ca750e099f79601f508bsalomon return stretched; 25337f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon} 25437f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon 2558c111f783f40470e697310244426362132979ad9krajcevski#ifndef SK_IGNORE_ETC1_SUPPORT 25637f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomonstatic GrTexture *load_etc1_texture(GrContext* ctx, const GrContentKey& optionalKey, 257f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomon const SkBitmap &bm, GrSurfaceDesc desc) { 25899ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski SkAutoTUnref<SkData> data(bm.pixelRef()->refEncodedData()); 2599c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski 2609c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski // Is this even encoded data? 2619c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski if (NULL == data) { 2629c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski return NULL; 2639c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski } 2649c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski 2659c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski // Is this a valid PKM encoded data? 2669c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski const uint8_t *bytes = data->bytes(); 26799ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski if (etc1_pkm_is_valid(bytes)) { 26899ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski uint32_t encodedWidth = etc1_pkm_get_width(bytes); 26999ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski uint32_t encodedHeight = etc1_pkm_get_height(bytes); 27099ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski 27199ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski // Does the data match the dimensions of the bitmap? If not, 27299ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski // then we don't know how to scale the image to match it... 27399ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski if (encodedWidth != static_cast<uint32_t>(bm.width()) || 27499ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski encodedHeight != static_cast<uint32_t>(bm.height())) { 27599ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski return NULL; 27699ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski } 27799ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski 27899ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski // Everything seems good... skip ahead to the data. 27999ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski bytes += ETC_PKM_HEADER_SIZE; 28099ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski desc.fConfig = kETC1_GrPixelConfig; 28199ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski } else if (SkKTXFile::is_ktx(bytes)) { 28299ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski SkKTXFile ktx(data); 2839c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski 28499ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski // Is it actually an ETC1 texture? 28540a1e11ebebe81586f3fec96408fdfd4b51123d2krajcevski if (!ktx.isCompressedFormat(SkTextureCompressor::kETC1_Format)) { 28699ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski return NULL; 28799ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski } 28899ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski 28999ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski // Does the data match the dimensions of the bitmap? If not, 29099ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski // then we don't know how to scale the image to match it... 29199ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski if (ktx.width() != bm.width() || ktx.height() != bm.height()) { 29299ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski return NULL; 293775b8199a214af57c3ea7969e9d456f5f3eb137fmtklein } 2949c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski 29599ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski bytes = ktx.pixelData(); 29699ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski desc.fConfig = kETC1_GrPixelConfig; 29799ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski } else { 2989c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski return NULL; 2999c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski } 3009c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski 30123e619cf462b2a8a500f3ca750e099f79601f508bsalomon return create_texture_for_bmp(ctx, optionalKey, desc, bm.pixelRef(), bytes, 0); 3029c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski} 3038c111f783f40470e697310244426362132979ad9krajcevski#endif // SK_IGNORE_ETC1_SUPPORT 3049c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski 30537f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomonstatic GrTexture* load_yuv_texture(GrContext* ctx, const GrContentKey& optionalKey, 306f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomon const SkBitmap& bm, const GrSurfaceDesc& desc) { 307ff58e4679b9473ce19abb81a3e50fc6a18f0981dsugoi // Subsets are not supported, the whole pixelRef is loaded when using YUV decoding 308518d83dbc1c899e316e8c896af5defb58b83120fsugoi SkPixelRef* pixelRef = bm.pixelRef(); 309692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi if ((NULL == pixelRef) || 310692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi (pixelRef->info().width() != bm.info().width()) || 311692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi (pixelRef->info().height() != bm.info().height())) { 312518d83dbc1c899e316e8c896af5defb58b83120fsugoi return NULL; 313518d83dbc1c899e316e8c896af5defb58b83120fsugoi } 314518d83dbc1c899e316e8c896af5defb58b83120fsugoi 315ba18f91b9f025dc53ab3cb19ea1407c55ad85937sugoi const bool useCache = optionalKey.isValid(); 316692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi SkYUVPlanesCache::Info yuvInfo; 317ba18f91b9f025dc53ab3cb19ea1407c55ad85937sugoi SkAutoTUnref<SkCachedData> cachedData; 318ba18f91b9f025dc53ab3cb19ea1407c55ad85937sugoi SkAutoMalloc storage; 319ba18f91b9f025dc53ab3cb19ea1407c55ad85937sugoi if (useCache) { 320ba18f91b9f025dc53ab3cb19ea1407c55ad85937sugoi cachedData.reset(SkYUVPlanesCache::FindAndRef(pixelRef->getGenerationID(), &yuvInfo)); 321ba18f91b9f025dc53ab3cb19ea1407c55ad85937sugoi } 322692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi 323518d83dbc1c899e316e8c896af5defb58b83120fsugoi void* planes[3]; 324ba18f91b9f025dc53ab3cb19ea1407c55ad85937sugoi if (cachedData.get()) { 325692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi planes[0] = (void*)cachedData->data(); 326692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi planes[1] = (uint8_t*)planes[0] + yuvInfo.fSizeInMemory[0]; 327692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi planes[2] = (uint8_t*)planes[1] + yuvInfo.fSizeInMemory[1]; 328692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi } else { 329692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi // Fetch yuv plane sizes for memory allocation. Here, width and height can be 330692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi // rounded up to JPEG block size and be larger than the image's width and height. 331692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi if (!pixelRef->getYUV8Planes(yuvInfo.fSize, NULL, NULL, NULL)) { 332692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi return NULL; 333692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi } 334518d83dbc1c899e316e8c896af5defb58b83120fsugoi 335692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi // Allocate the memory for YUV 336692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi size_t totalSize(0); 337692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi for (int i = 0; i < 3; ++i) { 338692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi yuvInfo.fRowBytes[i] = yuvInfo.fSize[i].fWidth; 339692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi yuvInfo.fSizeInMemory[i] = yuvInfo.fRowBytes[i] * yuvInfo.fSize[i].fHeight; 340692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi totalSize += yuvInfo.fSizeInMemory[i]; 341692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi } 342ba18f91b9f025dc53ab3cb19ea1407c55ad85937sugoi if (useCache) { 343ba18f91b9f025dc53ab3cb19ea1407c55ad85937sugoi cachedData.reset(SkResourceCache::NewCachedData(totalSize)); 344ba18f91b9f025dc53ab3cb19ea1407c55ad85937sugoi planes[0] = cachedData->writable_data(); 345ba18f91b9f025dc53ab3cb19ea1407c55ad85937sugoi } else { 346ba18f91b9f025dc53ab3cb19ea1407c55ad85937sugoi storage.reset(totalSize); 347ba18f91b9f025dc53ab3cb19ea1407c55ad85937sugoi planes[0] = storage.get(); 348ba18f91b9f025dc53ab3cb19ea1407c55ad85937sugoi } 349692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi planes[1] = (uint8_t*)planes[0] + yuvInfo.fSizeInMemory[0]; 350692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi planes[2] = (uint8_t*)planes[1] + yuvInfo.fSizeInMemory[1]; 351692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi 352692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi // Get the YUV planes and update plane sizes to actual image size 353692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi if (!pixelRef->getYUV8Planes(yuvInfo.fSize, planes, yuvInfo.fRowBytes, 354692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi &yuvInfo.fColorSpace)) { 355692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi return NULL; 356692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi } 357abaef86f2b37d8a939506a2076da07f6db456951rileya 358ba18f91b9f025dc53ab3cb19ea1407c55ad85937sugoi if (useCache) { 359ba18f91b9f025dc53ab3cb19ea1407c55ad85937sugoi // Decoding is done, cache the resulting YUV planes 360ba18f91b9f025dc53ab3cb19ea1407c55ad85937sugoi SkYUVPlanesCache::Add(pixelRef->getGenerationID(), cachedData, &yuvInfo); 361ba18f91b9f025dc53ab3cb19ea1407c55ad85937sugoi } 362518d83dbc1c899e316e8c896af5defb58b83120fsugoi } 363518d83dbc1c899e316e8c896af5defb58b83120fsugoi 364f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomon GrSurfaceDesc yuvDesc; 365518d83dbc1c899e316e8c896af5defb58b83120fsugoi yuvDesc.fConfig = kAlpha_8_GrPixelConfig; 366e30597375c19dfb5197fd065a3d1768401eb00fabsalomon SkAutoTUnref<GrTexture> yuvTextures[3]; 367518d83dbc1c899e316e8c896af5defb58b83120fsugoi for (int i = 0; i < 3; ++i) { 368692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi yuvDesc.fWidth = yuvInfo.fSize[i].fWidth; 369692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi yuvDesc.fHeight = yuvInfo.fSize[i].fHeight; 370e30597375c19dfb5197fd065a3d1768401eb00fabsalomon yuvTextures[i].reset( 371e30597375c19dfb5197fd065a3d1768401eb00fabsalomon ctx->refScratchTexture(yuvDesc, GrContext::kApprox_ScratchTexMatch)); 372e30597375c19dfb5197fd065a3d1768401eb00fabsalomon if (!yuvTextures[i] || 373e30597375c19dfb5197fd065a3d1768401eb00fabsalomon !yuvTextures[i]->writePixels(0, 0, yuvDesc.fWidth, yuvDesc.fHeight, 374692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi yuvDesc.fConfig, planes[i], yuvInfo.fRowBytes[i])) { 375518d83dbc1c899e316e8c896af5defb58b83120fsugoi return NULL; 376518d83dbc1c899e316e8c896af5defb58b83120fsugoi } 377518d83dbc1c899e316e8c896af5defb58b83120fsugoi } 378518d83dbc1c899e316e8c896af5defb58b83120fsugoi 379f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomon GrSurfaceDesc rtDesc = desc; 380518d83dbc1c899e316e8c896af5defb58b83120fsugoi rtDesc.fFlags = rtDesc.fFlags | 381f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomon kRenderTarget_GrSurfaceFlag | 382f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomon kNoStencil_GrSurfaceFlag; 383518d83dbc1c899e316e8c896af5defb58b83120fsugoi 38423e619cf462b2a8a500f3ca750e099f79601f508bsalomon GrTexture* result = create_texture_for_bmp(ctx, optionalKey, rtDesc, pixelRef, NULL, 0); 38537f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon if (!result) { 38637f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon return NULL; 387518d83dbc1c899e316e8c896af5defb58b83120fsugoi } 388518d83dbc1c899e316e8c896af5defb58b83120fsugoi 38937f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon GrRenderTarget* renderTarget = result->asRenderTarget(); 39037f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon SkASSERT(renderTarget); 39137f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon 39237f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon SkAutoTUnref<GrFragmentProcessor> 39337f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon yuvToRgbProcessor(GrYUVtoRGBEffect::Create(yuvTextures[0], yuvTextures[1], yuvTextures[2], 39437f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon yuvInfo.fColorSpace)); 39537f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon GrPaint paint; 39637f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon paint.addColorProcessor(yuvToRgbProcessor); 39737f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon SkRect r = SkRect::MakeWH(SkIntToScalar(yuvInfo.fSize[0].fWidth), 39837f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon SkIntToScalar(yuvInfo.fSize[0].fHeight)); 39937f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon GrContext::AutoRenderTarget autoRT(ctx, renderTarget); 40037f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon GrContext::AutoClip ac(ctx, GrContext::AutoClip::kWideOpen_InitialClip); 40137f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon ctx->drawRect(paint, SkMatrix::I(), r); 40237f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon 403518d83dbc1c899e316e8c896af5defb58b83120fsugoi return result; 404518d83dbc1c899e316e8c896af5defb58b83120fsugoi} 405518d83dbc1c899e316e8c896af5defb58b83120fsugoi 40637f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomonstatic GrTexture* create_unstretched_bitmap_texture(GrContext* ctx, 40737f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon const SkBitmap& origBitmap, 40837f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon const GrContentKey& optionalKey) { 409ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com SkBitmap tmpBitmap; 410ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 411ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com const SkBitmap* bitmap = &origBitmap; 4125782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com 413f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomon GrSurfaceDesc desc; 4140797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com generate_bitmap_texture_desc(*bitmap, &desc); 4155782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com 4160689d7b12e7c427a077b003d3d8ae759d86f798freed if (kIndex_8_SkColorType == bitmap->colorType()) { 417d2a6f4e419393d3c8d8fe332f11c4c6f88382e1dbsalomon if (ctx->isConfigTexturable(kIndex_8_GrPixelConfig)) { 418d4cb922ea1a85d381e88975b63664f6c0bf28cdbbsalomon size_t imageSize = GrCompressedFormatDataSize(kIndex_8_GrPixelConfig, 419d4cb922ea1a85d381e88975b63664f6c0bf28cdbbsalomon bitmap->width(), bitmap->height()); 420d4cb922ea1a85d381e88975b63664f6c0bf28cdbbsalomon SkAutoMalloc storage(imageSize); 421e79a2dab91a90e26b13bc1ec9b8c6264a1ab22e4bsalomon build_index8_data(storage.get(), origBitmap); 422ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 423ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com // our compressed data will be trimmed, so pass width() for its 424ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com // "rowBytes", since they are the same now. 42523e619cf462b2a8a500f3ca750e099f79601f508bsalomon return create_texture_for_bmp(ctx, optionalKey, desc, origBitmap.pixelRef(), 42623e619cf462b2a8a500f3ca750e099f79601f508bsalomon storage.get(), bitmap->width()); 427ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } else { 42828fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org origBitmap.copyTo(&tmpBitmap, kN32_SkColorType); 429ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com // now bitmap points to our temp, which has been promoted to 32bits 430ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com bitmap = &tmpBitmap; 4313adcc3403377c0b9a7afde6db8e0432325413a10commit-bot@chromium.org desc.fConfig = SkImageInfo2GrPixelConfig(bitmap->info()); 432ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 433309e86912445879651d52ebbedb67b4ff3f1516ckrajcevski } 4349c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski 4359c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski // Is this an ETC1 encoded texture? 4368c111f783f40470e697310244426362132979ad9krajcevski#ifndef SK_IGNORE_ETC1_SUPPORT 437d2a6f4e419393d3c8d8fe332f11c4c6f88382e1dbsalomon // Make sure that the underlying device supports ETC1 textures before we go ahead 438d2a6f4e419393d3c8d8fe332f11c4c6f88382e1dbsalomon // and check the data. 439d2a6f4e419393d3c8d8fe332f11c4c6f88382e1dbsalomon else if (ctx->isConfigTexturable(kETC1_GrPixelConfig) 440d2a6f4e419393d3c8d8fe332f11c4c6f88382e1dbsalomon // If the bitmap had compressed data and was then uncompressed, it'll still return 441d2a6f4e419393d3c8d8fe332f11c4c6f88382e1dbsalomon // compressed data on 'refEncodedData' and upload it. Probably not good, since if 442d2a6f4e419393d3c8d8fe332f11c4c6f88382e1dbsalomon // the bitmap has available pixels, then they might not be what the decompressed 443d2a6f4e419393d3c8d8fe332f11c4c6f88382e1dbsalomon // data is. 444d2a6f4e419393d3c8d8fe332f11c4c6f88382e1dbsalomon && !(bitmap->readyToDraw())) { 44537f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon GrTexture *texture = load_etc1_texture(ctx, optionalKey, *bitmap, desc); 44649f085dddff10473b6ebf832a974288300224e60bsalomon if (texture) { 4479c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski return texture; 4489c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski } 4495782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com } 4508c111f783f40470e697310244426362132979ad9krajcevski#endif // SK_IGNORE_ETC1_SUPPORT 451ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 452d2a6f4e419393d3c8d8fe332f11c4c6f88382e1dbsalomon GrTexture *texture = load_yuv_texture(ctx, optionalKey, *bitmap, desc); 453d2a6f4e419393d3c8d8fe332f11c4c6f88382e1dbsalomon if (texture) { 454d2a6f4e419393d3c8d8fe332f11c4c6f88382e1dbsalomon return texture; 455518d83dbc1c899e316e8c896af5defb58b83120fsugoi } 456d2a6f4e419393d3c8d8fe332f11c4c6f88382e1dbsalomon 4577f4ad5a30ff745e666579d2b518dfd0c1aa49596bsalomon@google.com SkAutoLockPixels alp(*bitmap); 4587f4ad5a30ff745e666579d2b518dfd0c1aa49596bsalomon@google.com if (!bitmap->readyToDraw()) { 4597f4ad5a30ff745e666579d2b518dfd0c1aa49596bsalomon@google.com return NULL; 4607f4ad5a30ff745e666579d2b518dfd0c1aa49596bsalomon@google.com } 46150a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org 46223e619cf462b2a8a500f3ca750e099f79601f508bsalomon return create_texture_for_bmp(ctx, optionalKey, desc, origBitmap.pixelRef(), 46323e619cf462b2a8a500f3ca750e099f79601f508bsalomon bitmap->getPixels(), bitmap->rowBytes()); 46437f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon} 46537f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon 46637f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomonstatic GrTexture* create_bitmap_texture(GrContext* ctx, 46737f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon const SkBitmap& bmp, 46837f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon Stretch stretch, 46937f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon const GrContentKey& unstretchedKey, 47037f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon const GrContentKey& stretchedKey) { 47137f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon if (kNo_Stretch != stretch) { 47237f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon SkAutoTUnref<GrTexture> unstretched; 47337f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon // Check if we have the unstretched version in the cache, if not create it. 47437f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon if (unstretchedKey.isValid()) { 47537f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon unstretched.reset(ctx->findAndRefCachedTexture(unstretchedKey)); 47637f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon } 47737f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon if (!unstretched) { 47837f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon unstretched.reset(create_unstretched_bitmap_texture(ctx, bmp, unstretchedKey)); 47937f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon if (!unstretched) { 48037f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon return NULL; 48137f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon } 48237f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon } 48323e619cf462b2a8a500f3ca750e099f79601f508bsalomon GrTexture* stretched = stretch_texture_to_next_pot(unstretched, stretch, bmp.pixelRef(), 48423e619cf462b2a8a500f3ca750e099f79601f508bsalomon stretchedKey); 48523e619cf462b2a8a500f3ca750e099f79601f508bsalomon return stretched; 48637f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon } 48737f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon 48837f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon return create_unstretched_bitmap_texture(ctx, bmp, unstretchedKey); 48937f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon 490ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 491ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 4920797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.combool GrIsBitmapInCache(const GrContext* ctx, 4930797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com const SkBitmap& bitmap, 4940797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com const GrTextureParams* params) { 49588425565259809bc1b0aac116d87f3fc8d212f43bsalomon Stretch stretch = get_stretch_type(ctx, bitmap.width(), bitmap.height(), params); 49688425565259809bc1b0aac116d87f3fc8d212f43bsalomon 49788425565259809bc1b0aac116d87f3fc8d212f43bsalomon // Handle the case where the bitmap is explicitly texture backed. 49888425565259809bc1b0aac116d87f3fc8d212f43bsalomon GrTexture* texture = bitmap.getTexture(); 49988425565259809bc1b0aac116d87f3fc8d212f43bsalomon if (texture) { 50088425565259809bc1b0aac116d87f3fc8d212f43bsalomon if (kNo_Stretch == stretch) { 50188425565259809bc1b0aac116d87f3fc8d212f43bsalomon return true; 50288425565259809bc1b0aac116d87f3fc8d212f43bsalomon } 50388425565259809bc1b0aac116d87f3fc8d212f43bsalomon // No keys for volatile bitmaps. 50488425565259809bc1b0aac116d87f3fc8d212f43bsalomon if (bitmap.isVolatile()) { 50588425565259809bc1b0aac116d87f3fc8d212f43bsalomon return false; 50688425565259809bc1b0aac116d87f3fc8d212f43bsalomon } 50788425565259809bc1b0aac116d87f3fc8d212f43bsalomon const GrContentKey& key = texture->getContentKey(); 50888425565259809bc1b0aac116d87f3fc8d212f43bsalomon if (!key.isValid()) { 50988425565259809bc1b0aac116d87f3fc8d212f43bsalomon return false; 51088425565259809bc1b0aac116d87f3fc8d212f43bsalomon } 51123e619cf462b2a8a500f3ca750e099f79601f508bsalomon GrContentKey stretchedKey; 51223e619cf462b2a8a500f3ca750e099f79601f508bsalomon make_stretched_key(key, stretch, &stretchedKey); 51323e619cf462b2a8a500f3ca750e099f79601f508bsalomon return ctx->isResourceInCache(stretchedKey); 5149ed7f573491217079cccf1d81792cf4520a3c0d0bsalomon } 5159ed7f573491217079cccf1d81792cf4520a3c0d0bsalomon 51637f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon // We don't cache volatile bitmaps 51737f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon if (bitmap.isVolatile()) { 51837f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon return false; 51937f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon } 52037f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon 52123e619cf462b2a8a500f3ca750e099f79601f508bsalomon GrContentKey key, stretchedKey; 52223e619cf462b2a8a500f3ca750e099f79601f508bsalomon make_bitmap_keys(bitmap, stretch, &key, &stretchedKey); 52323e619cf462b2a8a500f3ca750e099f79601f508bsalomon return ctx->isResourceInCache((kNo_Stretch == stretch) ? key : stretchedKey); 5240797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com} 525ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 526bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomonGrTexture* GrRefCachedBitmapTexture(GrContext* ctx, 527bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon const SkBitmap& bitmap, 528bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon const GrTextureParams* params) { 52988425565259809bc1b0aac116d87f3fc8d212f43bsalomon 53088425565259809bc1b0aac116d87f3fc8d212f43bsalomon Stretch stretch = get_stretch_type(ctx, bitmap.width(), bitmap.height(), params); 53188425565259809bc1b0aac116d87f3fc8d212f43bsalomon 53288425565259809bc1b0aac116d87f3fc8d212f43bsalomon GrTexture* result = bitmap.getTexture(); 5339ed7f573491217079cccf1d81792cf4520a3c0d0bsalomon if (result) { 53488425565259809bc1b0aac116d87f3fc8d212f43bsalomon if (kNo_Stretch == stretch) { 53588425565259809bc1b0aac116d87f3fc8d212f43bsalomon return SkRef(result); 53688425565259809bc1b0aac116d87f3fc8d212f43bsalomon } 53723e619cf462b2a8a500f3ca750e099f79601f508bsalomon GrContentKey stretchedKey; 53888425565259809bc1b0aac116d87f3fc8d212f43bsalomon // Don't create a key for the resized version if the bmp is volatile. 53988425565259809bc1b0aac116d87f3fc8d212f43bsalomon if (!bitmap.isVolatile()) { 54088425565259809bc1b0aac116d87f3fc8d212f43bsalomon const GrContentKey& key = result->getContentKey(); 54188425565259809bc1b0aac116d87f3fc8d212f43bsalomon if (key.isValid()) { 54223e619cf462b2a8a500f3ca750e099f79601f508bsalomon make_stretched_key(key, stretch, &stretchedKey); 54323e619cf462b2a8a500f3ca750e099f79601f508bsalomon GrTexture* stretched = ctx->findAndRefCachedTexture(stretchedKey); 54488425565259809bc1b0aac116d87f3fc8d212f43bsalomon if (stretched) { 54588425565259809bc1b0aac116d87f3fc8d212f43bsalomon return stretched; 54688425565259809bc1b0aac116d87f3fc8d212f43bsalomon } 54788425565259809bc1b0aac116d87f3fc8d212f43bsalomon } 54888425565259809bc1b0aac116d87f3fc8d212f43bsalomon } 54923e619cf462b2a8a500f3ca750e099f79601f508bsalomon return stretch_texture_to_next_pot(result, stretch, bitmap.pixelRef(), stretchedKey); 5509ed7f573491217079cccf1d81792cf4520a3c0d0bsalomon } 55124f3ad1bbb44916cae33f5d3cf2a20af4bbc381frileya@google.com 55237f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon GrContentKey key, resizedKey; 5539c2ea846351a29208cb4a36301ee611e7fb384earobertphillips@google.com 55437f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon if (!bitmap.isVolatile()) { 5550797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com // If the bitmap isn't changing try to find a cached copy first. 55623e619cf462b2a8a500f3ca750e099f79601f508bsalomon make_bitmap_keys(bitmap, stretch, &key, &resizedKey); 5574b86e3428b115202e82d49a0914ea8ab6dc25940bsalomon@google.com 55837f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon result = ctx->findAndRefCachedTexture(resizedKey.isValid() ? resizedKey : key); 55937f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon if (result) { 56037f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon return result; 56137f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon } 562e137db8569e7a10d809980609688b3acfaec612absalomon } 56337f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon 56437f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon result = create_bitmap_texture(ctx, bitmap, stretch, key, resizedKey); 56537f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon if (result) { 56637f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon return result; 567e137db8569e7a10d809980609688b3acfaec612absalomon } 568e137db8569e7a10d809980609688b3acfaec612absalomon 56937f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon SkDebugf("---- failed to create texture for cache [%d %d]\n", 57037f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon bitmap.width(), bitmap.height()); 57137f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon 57237f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon return NULL; 57337f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon} 57424f3ad1bbb44916cae33f5d3cf2a20af4bbc381frileya@google.com/////////////////////////////////////////////////////////////////////////////// 57524f3ad1bbb44916cae33f5d3cf2a20af4bbc381frileya@google.com 57615a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org// alphatype is ignore for now, but if GrPixelConfig is expanded to encompass 57715a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org// alpha info, that will be considered. 578fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverthGrPixelConfig SkImageInfo2GrPixelConfig(SkColorType ct, SkAlphaType, SkColorProfileType pt) { 57915a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org switch (ct) { 58015a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org case kUnknown_SkColorType: 58115a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org return kUnknown_GrPixelConfig; 58215a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org case kAlpha_8_SkColorType: 58315a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org return kAlpha_8_GrPixelConfig; 58415a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org case kRGB_565_SkColorType: 58515a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org return kRGB_565_GrPixelConfig; 58615a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org case kARGB_4444_SkColorType: 58715a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org return kRGBA_4444_GrPixelConfig; 58815a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org case kRGBA_8888_SkColorType: 589fe43c40d5dbfff6c3726404e4bb31e2f84a95c5cjvanverth// if (kSRGB_SkColorProfileType == pt) { 590fe43c40d5dbfff6c3726404e4bb31e2f84a95c5cjvanverth// return kSRGBA_8888_GrPixelConfig; 591fe43c40d5dbfff6c3726404e4bb31e2f84a95c5cjvanverth// } 59215a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org return kRGBA_8888_GrPixelConfig; 59315a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org case kBGRA_8888_SkColorType: 59415a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org return kBGRA_8888_GrPixelConfig; 59515a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org case kIndex_8_SkColorType: 59615a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org return kIndex_8_GrPixelConfig; 59715a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org } 59815a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org SkASSERT(0); // shouldn't get here 59915a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org return kUnknown_GrPixelConfig; 60015a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org} 60115a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org 602fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverthbool GrPixelConfig2ColorAndProfileType(GrPixelConfig config, SkColorType* ctOut, 603fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverth SkColorProfileType* ptOut) { 604bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com SkColorType ct; 605fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverth SkColorProfileType pt = kLinear_SkColorProfileType; 606bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com switch (config) { 607bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com case kAlpha_8_GrPixelConfig: 608bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com ct = kAlpha_8_SkColorType; 609bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com break; 610bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com case kIndex_8_GrPixelConfig: 611bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com ct = kIndex_8_SkColorType; 612bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com break; 613bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com case kRGB_565_GrPixelConfig: 614bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com ct = kRGB_565_SkColorType; 615bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com break; 616bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com case kRGBA_4444_GrPixelConfig: 617bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com ct = kARGB_4444_SkColorType; 618bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com break; 619bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com case kRGBA_8888_GrPixelConfig: 620bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com ct = kRGBA_8888_SkColorType; 621bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com break; 622bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com case kBGRA_8888_GrPixelConfig: 623bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com ct = kBGRA_8888_SkColorType; 624bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com break; 625fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverth case kSRGBA_8888_GrPixelConfig: 626fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverth ct = kRGBA_8888_SkColorType; 627fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverth pt = kSRGB_SkColorProfileType; 628fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverth break; 629bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com default: 630bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com return false; 631bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com } 632bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com if (ctOut) { 633bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com *ctOut = ct; 634bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com } 635fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverth if (ptOut) { 636fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverth *ptOut = pt; 637fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverth } 638bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com return true; 639bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com} 6408dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org 6418dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 6428dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org 64383d081ae1d731b5039e99823620f5e287542ee39bsalomonvoid SkPaint2GrPaintNoShader(GrContext* context, const SkPaint& skPaint, GrColor paintColor, 6448dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org bool constantColor, GrPaint* grPaint) { 6458dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org 6468dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org grPaint->setDither(skPaint.isDither()); 6478dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org grPaint->setAntiAlias(skPaint.isAntiAlias()); 6488dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org 6498dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org SkXfermode* mode = skPaint.getXfermode(); 650378092f3d10b1dd62967f419c35cfefec7c10ee7egdaniel GrXPFactory* xpFactory = NULL; 65158136167fc596fb945b58b34f500cf370c0dec7cegdaniel if (!SkXfermode::AsXPFactory(mode, &xpFactory)) { 6528dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org // Fall back to src-over 653c016fb8f9fb53dd8d4936c5e9e16a9dc99ab392eegdaniel xpFactory = GrPorterDuffXPFactory::Create(SkXfermode::kSrcOver_Mode); 6548dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org } 655378092f3d10b1dd62967f419c35cfefec7c10ee7egdaniel SkASSERT(xpFactory); 656378092f3d10b1dd62967f419c35cfefec7c10ee7egdaniel grPaint->setXPFactory(xpFactory)->unref(); 657775b8199a214af57c3ea7969e9d456f5f3eb137fmtklein 6589de5b514d38c5b36066bcdc14fba2f7e5196d372dandov //set the color of the paint to the one of the parameter 65983d081ae1d731b5039e99823620f5e287542ee39bsalomon grPaint->setColor(paintColor); 6608dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org 6618dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org SkColorFilter* colorFilter = skPaint.getColorFilter(); 66249f085dddff10473b6ebf832a974288300224e60bsalomon if (colorFilter) { 6638dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org // if the source color is a constant then apply the filter here once rather than per pixel 6648dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org // in a shader. 6658dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org if (constantColor) { 6668dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org SkColor filtered = colorFilter->filterColor(skPaint.getColor()); 6678dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org grPaint->setColor(SkColor2GrColor(filtered)); 6688dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org } else { 669b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt SkAutoTUnref<GrFragmentProcessor> fp(colorFilter->asFragmentProcessor(context)); 670b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt if (fp.get()) { 671b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt grPaint->addColorProcessor(fp); 6728dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org } 6738dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org } 6748dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org } 675f461a8fdf642ba713dcdfb217534652df1eac278krajcevski 676f461a8fdf642ba713dcdfb217534652df1eac278krajcevski#ifndef SK_IGNORE_GPU_DITHER 677f461a8fdf642ba713dcdfb217534652df1eac278krajcevski // If the dither flag is set, then we need to see if the underlying context 678f461a8fdf642ba713dcdfb217534652df1eac278krajcevski // supports it. If not, then install a dither effect. 679f461a8fdf642ba713dcdfb217534652df1eac278krajcevski if (skPaint.isDither() && grPaint->numColorStages() > 0) { 680f461a8fdf642ba713dcdfb217534652df1eac278krajcevski // What are we rendering into? 681f461a8fdf642ba713dcdfb217534652df1eac278krajcevski const GrRenderTarget *target = context->getRenderTarget(); 68249f085dddff10473b6ebf832a974288300224e60bsalomon SkASSERT(target); 683f461a8fdf642ba713dcdfb217534652df1eac278krajcevski 684f461a8fdf642ba713dcdfb217534652df1eac278krajcevski // Suspect the dithering flag has no effect on these configs, otherwise 685f461a8fdf642ba713dcdfb217534652df1eac278krajcevski // fall back on setting the appropriate state. 686f461a8fdf642ba713dcdfb217534652df1eac278krajcevski if (target->config() == kRGBA_8888_GrPixelConfig || 687f461a8fdf642ba713dcdfb217534652df1eac278krajcevski target->config() == kBGRA_8888_GrPixelConfig) { 688f461a8fdf642ba713dcdfb217534652df1eac278krajcevski // The dither flag is set and the target is likely 689f461a8fdf642ba713dcdfb217534652df1eac278krajcevski // not going to be dithered by the GPU. 690b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt SkAutoTUnref<GrFragmentProcessor> fp(GrDitherEffect::Create()); 691b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt if (fp.get()) { 692b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt grPaint->addColorProcessor(fp); 693f461a8fdf642ba713dcdfb217534652df1eac278krajcevski grPaint->setDither(false); 694f461a8fdf642ba713dcdfb217534652df1eac278krajcevski } 695f461a8fdf642ba713dcdfb217534652df1eac278krajcevski } 696f461a8fdf642ba713dcdfb217534652df1eac278krajcevski } 697f461a8fdf642ba713dcdfb217534652df1eac278krajcevski#endif 6988dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org} 6998dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org 7005531d51ce7426bdae7563547326fcf0bf926a083joshualittvoid SkPaint2GrPaintShader(GrContext* context, const SkPaint& skPaint, const SkMatrix& viewM, 7018dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org bool constantColor, GrPaint* grPaint) { 7028dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org SkShader* shader = skPaint.getShader(); 7038dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org if (NULL == shader) { 7049de5b514d38c5b36066bcdc14fba2f7e5196d372dandov SkPaint2GrPaintNoShader(context, skPaint, SkColor2GrColor(skPaint.getColor()), 7059de5b514d38c5b36066bcdc14fba2f7e5196d372dandov constantColor, grPaint); 7068dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org return; 7078dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org } 7088dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org 70983d081ae1d731b5039e99823620f5e287542ee39bsalomon GrColor paintColor = SkColor2GrColor(skPaint.getColor()); 710f461a8fdf642ba713dcdfb217534652df1eac278krajcevski 711f461a8fdf642ba713dcdfb217534652df1eac278krajcevski // Start a new block here in order to preserve our context state after calling 712b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt // asFragmentProcessor(). Since these calls get passed back to the client, we don't really 713f461a8fdf642ba713dcdfb217534652df1eac278krajcevski // want them messing around with the context. 714f461a8fdf642ba713dcdfb217534652df1eac278krajcevski { 715b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt // SkShader::asFragmentProcessor() may do offscreen rendering. Save off the current RT, 7165531d51ce7426bdae7563547326fcf0bf926a083joshualitt // and clip 717f461a8fdf642ba713dcdfb217534652df1eac278krajcevski GrContext::AutoRenderTarget art(context, NULL); 718f461a8fdf642ba713dcdfb217534652df1eac278krajcevski GrContext::AutoClip ac(context, GrContext::AutoClip::kWideOpen_InitialClip); 719f461a8fdf642ba713dcdfb217534652df1eac278krajcevski 72083d081ae1d731b5039e99823620f5e287542ee39bsalomon // Allow the shader to modify paintColor and also create an effect to be installed as 72183d081ae1d731b5039e99823620f5e287542ee39bsalomon // the first color effect on the GrPaint. 722b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrFragmentProcessor* fp = NULL; 7235531d51ce7426bdae7563547326fcf0bf926a083joshualitt if (shader->asFragmentProcessor(context, skPaint, viewM, NULL, &paintColor, &fp) && fp) { 724b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt grPaint->addColorProcessor(fp)->unref(); 725f461a8fdf642ba713dcdfb217534652df1eac278krajcevski constantColor = false; 726f461a8fdf642ba713dcdfb217534652df1eac278krajcevski } 7278dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org } 728f461a8fdf642ba713dcdfb217534652df1eac278krajcevski 729b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt // The grcolor is automatically set when calling asFragmentProcessor. 7309de5b514d38c5b36066bcdc14fba2f7e5196d372dandov // If the shader can be seen as an effect it returns true and adds its effect to the grpaint. 73183d081ae1d731b5039e99823620f5e287542ee39bsalomon SkPaint2GrPaintNoShader(context, skPaint, paintColor, constantColor, grPaint); 7328dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org} 733