SkGr.cpp revision 5531d51ce7426bdae7563547326fcf0bf926a083
1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 29b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org * Copyright 2010 Google Inc. 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 49b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org * Use of this source code is governed by a BSD-style license that can be 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */ 79b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org 89b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org#include "SkGr.h" 9ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 109b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org#include "GrDrawTargetCaps.h" 119b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org#include "GrGpu.h" 129b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org#include "GrXferProcessor.h" 139fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org#include "SkColorFilter.h" 148a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com#include "SkConfig8888.h" 15fb0b0edd86d71bb423fa921eaac1e2071602115cvandebo@chromium.org#include "SkData.h" 1628be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org#include "SkMessageBus.h" 179b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org#include "SkPixelRef.h" 18a518086928494319b8968abc09808eff492c194fvandebo@chromium.org#include "SkTextureCompressor.h" 1928be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org#include "effects/GrDitherEffect.h" 20eb6c7596af1a1fc7860e27ff2f678a33b2576c0fvandebo@chromium.org#include "effects/GrPorterDuffXferProcessor.h" 2177bcaa324a574584331322d98768582d9232f7fcvandebo@chromium.org#include "effects/GrYUVtoRGBEffect.h" 2277bcaa324a574584331322d98768582d9232f7fcvandebo@chromium.org 23da912d61ede86dd3dfa8f645c6f3977f2183812bvandebo@chromium.org#ifndef SK_IGNORE_ETC1_SUPPORT 249b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org# include "ktx.h" 2577bcaa324a574584331322d98768582d9232f7fcvandebo@chromium.org# include "etc1.h" 269db86bb9cd1b77be0afc504ccc07026e4282d7e7ctguil@chromium.org#endif 279b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org 289b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org/* Fill out buffer with the compressed format Ganesh expects from a colortable 2928be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org based bitmap. [palette (colortable) + indices]. 3028be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org 3128be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org At the moment Ganesh only supports 8bit version. If Ganesh allowed we others 329b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org we could detect that the colortable.count is <= 16, and then repack the 339b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org indices as nibbles to save RAM, but it would take more time (i.e. a lot 349b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org slower than memcpy), so skipping that for now. 359fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org 369b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org Ganesh wants a full 256 palette entry, even though Skia's ctable is only as big 379b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org as the colortable.count says it is. 38094316bd284372c2a3d8ef02eec589901e503c59vandebo@chromium.org */ 39cae5fba82e687d674b076b10cdc8aba46e1ac3b3vandebo@chromium.orgstatic void build_index8_data(void* buffer, const SkBitmap& bitmap) { 40cae5fba82e687d674b076b10cdc8aba46e1ac3b3vandebo@chromium.org SkASSERT(kIndex_8_SkColorType == bitmap.colorType()); 41094316bd284372c2a3d8ef02eec589901e503c59vandebo@chromium.org 42cae5fba82e687d674b076b10cdc8aba46e1ac3b3vandebo@chromium.org SkAutoLockPixels alp(bitmap); 43cae5fba82e687d674b076b10cdc8aba46e1ac3b3vandebo@chromium.org if (!bitmap.readyToDraw()) { 44094316bd284372c2a3d8ef02eec589901e503c59vandebo@chromium.org SkDEBUGFAIL("bitmap not ready to draw!"); 45cae5fba82e687d674b076b10cdc8aba46e1ac3b3vandebo@chromium.org return; 46cae5fba82e687d674b076b10cdc8aba46e1ac3b3vandebo@chromium.org } 479b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org 489b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org SkColorTable* ctable = bitmap.getColorTable(); 499fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org char* dst = (char*)buffer; 5028be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org 5128be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org const int count = ctable->count(); 5228be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org 5328be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org SkDstPixelInfo dstPI; 5428be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org dstPI.fColorType = kRGBA_8888_SkColorType; 5528be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org dstPI.fAlphaType = kPremul_SkAlphaType; 5628be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org dstPI.fPixels = buffer; 57769fa6a013baca6d7404e2bf096a34a7e3635fa5ctguil@chromium.org dstPI.fRowBytes = count * sizeof(SkPMColor); 5828be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org 59769fa6a013baca6d7404e2bf096a34a7e3635fa5ctguil@chromium.org SkSrcPixelInfo srcPI; 6028be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org srcPI.fColorType = kN32_SkColorType; 61769fa6a013baca6d7404e2bf096a34a7e3635fa5ctguil@chromium.org srcPI.fAlphaType = kPremul_SkAlphaType; 6228be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org srcPI.fPixels = ctable->readColors(); 6328be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org srcPI.fRowBytes = count * sizeof(SkPMColor); 6428be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org 6528be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org srcPI.convertPixelsTo(&dstPI, count, 1); 6628be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org 6728be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org // always skip a full 256 number of entries, even if we memcpy'd fewer 689fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org dst += 256 * sizeof(GrColor); 699a87cee904e2d8f0ea6a0e7e3ca864262a8cb7c4bungeman@google.com 709a87cee904e2d8f0ea6a0e7e3ca864262a8cb7c4bungeman@google.com if ((unsigned)bitmap.width() == bitmap.rowBytes()) { 719a87cee904e2d8f0ea6a0e7e3ca864262a8cb7c4bungeman@google.com memcpy(dst, bitmap.getPixels(), bitmap.getSize()); 7228be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org } else { 73769fa6a013baca6d7404e2bf096a34a7e3635fa5ctguil@chromium.org // need to trim off the extra bytes per row 7428be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org size_t width = bitmap.width(); 7528be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org size_t rowBytes = bitmap.rowBytes(); 7628be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org const char* src = (const char*)bitmap.getPixels(); 7728be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org for (int y = 0; y < bitmap.height(); y++) { 7828be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org memcpy(dst, src, width); 7928be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org src += rowBytes; 809510ccc06bbfa5e888f66578042674be98d8ac60ctguil@chromium.org dst += width; 819510ccc06bbfa5e888f66578042674be98d8ac60ctguil@chromium.org } 8228be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org } 8328be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org} 84769fa6a013baca6d7404e2bf096a34a7e3635fa5ctguil@chromium.org 8528be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org//////////////////////////////////////////////////////////////////////////////// 8628be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org 8728be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.orgstatic void generate_bitmap_cache_id(const SkBitmap& bitmap, GrCacheID* id) { 8828be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org // Our id includes the offset, width, and height so that bitmaps created by extractSubset() 8928be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org // are unique. 90769fa6a013baca6d7404e2bf096a34a7e3635fa5ctguil@chromium.org uint32_t genID = bitmap.getGenerationID(); 9128be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org SkIPoint origin = bitmap.pixelRefOrigin(); 92769fa6a013baca6d7404e2bf096a34a7e3635fa5ctguil@chromium.org int16_t width = SkToS16(bitmap.width()); 9328be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org int16_t height = SkToS16(bitmap.height()); 9428be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org 9528be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org GrCacheID::Key key; 9628be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org memcpy(key.fData8 + 0, &genID, 4); 9728be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org memcpy(key.fData8 + 4, &origin.fX, 4); 9828be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org memcpy(key.fData8 + 8, &origin.fY, 4); 9928be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org memcpy(key.fData8 + 12, &width, 2); 10028be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org memcpy(key.fData8 + 14, &height, 2); 10128be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org static const size_t kKeyDataSize = 16; 10228be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org memset(key.fData8 + kKeyDataSize, 0, sizeof(key) - kKeyDataSize); 10328be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org GR_STATIC_ASSERT(sizeof(key) >= kKeyDataSize); 104b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org static const GrCacheID::Domain gBitmapTextureDomain = GrCacheID::GenerateDomain(); 105b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org id->reset(gBitmapTextureDomain, key); 106b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org} 107b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org 108b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.orgstatic void generate_bitmap_texture_desc(const SkBitmap& bitmap, GrSurfaceDesc* desc) { 109b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org desc->fFlags = kNone_GrSurfaceFlags; 110b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org desc->fWidth = bitmap.width(); 111b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org desc->fHeight = bitmap.height(); 112b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org desc->fConfig = SkImageInfo2GrPixelConfig(bitmap.info()); 113b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org desc->fSampleCnt = 0; 114b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org} 115b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org 116b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.orgnamespace { 1179fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org 1189fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org// When the SkPixelRef genID changes, invalidate a corresponding GrResource described by key. 1199fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.orgclass GrResourceInvalidator : public SkPixelRef::GenIDChangeListener { 1209fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.orgpublic: 1219fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org explicit GrResourceInvalidator(GrResourceKey key) : fKey(key) {} 1229fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.orgprivate: 1239fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org GrResourceKey fKey; 1249fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org 1259fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org virtual void onChange() SK_OVERRIDE { 1269fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org const GrResourceInvalidatedMessage message = { fKey }; 1279fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org SkMessageBus<GrResourceInvalidatedMessage>::Post(message); 1289fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org } 1299fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org}; 1309fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org 1319fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org} // namespace 1329fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org 1339fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.orgstatic void add_genID_listener(GrResourceKey key, SkPixelRef* pixelRef) { 1349fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org SkASSERT(pixelRef); 1359fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org pixelRef->addGenIDChangeListener(SkNEW_ARGS(GrResourceInvalidator, (key))); 1369fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org} 1379fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org 1389fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.orgstatic GrTexture* sk_gr_allocate_texture(GrContext* ctx, 1399fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org bool cache, 1409fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org const GrTextureParams* params, 1419fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org const SkBitmap& bm, 1429fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org GrSurfaceDesc desc, 1439fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org const void* pixels, 1449fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org size_t rowBytes) { 1459fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org GrTexture* result; 1469fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org if (cache) { 1479fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org // This texture is likely to be used again so leave it in the cache 1489fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org GrCacheID cacheID; 1499fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org generate_bitmap_cache_id(bm, &cacheID); 1509fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org 1519fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org GrResourceKey key; 1529fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org result = ctx->createTexture(params, desc, cacheID, pixels, rowBytes, &key); 1539fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org if (result) { 1549fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org add_genID_listener(key, bm.pixelRef()); 1559fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org } 1569fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org } else { 1579fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org // This texture is unlikely to be used again (in its present form) so 1589fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org // just use a scratch texture. This will remove the texture from the 1599fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org // cache so no one else can find it. Additionally, once unlocked, the 1609fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org // scratch texture will go to the end of the list for purging so will 1619fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org // likely be available for this volatile bitmap the next time around. 1629fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org result = ctx->refScratchTexture(desc, GrContext::kExact_ScratchTexMatch); 1639fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org if (pixels) { 1649fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org result->writePixels(0, 0, bm.width(), bm.height(), desc.fConfig, pixels, rowBytes); 1659fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org } 1669fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org } 1679fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org return result; 1689fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org} 1699fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org 1709fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org#ifndef SK_IGNORE_ETC1_SUPPORT 1719fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.orgstatic GrTexture *load_etc1_texture(GrContext* ctx, bool cache, 1729fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org const GrTextureParams* params, 1739fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org const SkBitmap &bm, GrSurfaceDesc desc) { 1749fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org SkAutoTUnref<SkData> data(bm.pixelRef()->refEncodedData()); 1759fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org 1769fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org // Is this even encoded data? 1779fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org if (NULL == data) { 1789fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org return NULL; 1799fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org } 1809fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org 1819fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org // Is this a valid PKM encoded data? 1829fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org const uint8_t *bytes = data->bytes(); 1839fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org if (etc1_pkm_is_valid(bytes)) { 1849fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org uint32_t encodedWidth = etc1_pkm_get_width(bytes); 1859fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org uint32_t encodedHeight = etc1_pkm_get_height(bytes); 1869fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org 1879fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org // Does the data match the dimensions of the bitmap? If not, 1889fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org // then we don't know how to scale the image to match it... 1899fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org if (encodedWidth != static_cast<uint32_t>(bm.width()) || 1909fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org encodedHeight != static_cast<uint32_t>(bm.height())) { 1919fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org return NULL; 1929fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org } 1939fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org 1949fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org // Everything seems good... skip ahead to the data. 1959fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org bytes += ETC_PKM_HEADER_SIZE; 1969fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org desc.fConfig = kETC1_GrPixelConfig; 1979fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org } else if (SkKTXFile::is_ktx(bytes)) { 1989fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org SkKTXFile ktx(data); 1999fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org 2009fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org // Is it actually an ETC1 texture? 2019fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org if (!ktx.isCompressedFormat(SkTextureCompressor::kETC1_Format)) { 2029fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org return NULL; 2039fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org } 2049fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org 2059fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org // Does the data match the dimensions of the bitmap? If not, 2069fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org // then we don't know how to scale the image to match it... 2079fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org if (ktx.width() != bm.width() || ktx.height() != bm.height()) { 2089fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org return NULL; 2099fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org } 2109fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org 2119fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org bytes = ktx.pixelData(); 2129fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org desc.fConfig = kETC1_GrPixelConfig; 2139fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org } else { 2149fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org return NULL; 2159fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org } 2169fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org 2179fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org return sk_gr_allocate_texture(ctx, cache, params, bm, desc, bytes, 0); 2189fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org} 2199fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org#endif // SK_IGNORE_ETC1_SUPPORT 2209fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org 2219fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.orgstatic GrTexture *load_yuv_texture(GrContext* ctx, bool cache, const GrTextureParams* params, 2229fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org const SkBitmap& bm, const GrSurfaceDesc& desc) { 2239fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org // Subsets are not supported, the whole pixelRef is loaded when using YUV decoding 2249fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org if ((bm.pixelRef()->info().width() != bm.info().width()) || 2259fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org (bm.pixelRef()->info().height() != bm.info().height())) { 2269fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org return NULL; 2279fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org } 2289fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org 2299fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org SkPixelRef* pixelRef = bm.pixelRef(); 2309fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org SkISize yuvSizes[3]; 2318887ede82465687355c7a1c51e4553e99b2fb15avandebo@chromium.org if ((NULL == pixelRef) || !pixelRef->getYUV8Planes(yuvSizes, NULL, NULL, NULL)) { 2329fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org return NULL; 2338887ede82465687355c7a1c51e4553e99b2fb15avandebo@chromium.org } 2349fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org 2359fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org // Allocate the memory for YUV 2368887ede82465687355c7a1c51e4553e99b2fb15avandebo@chromium.org size_t totalSize(0); 2378887ede82465687355c7a1c51e4553e99b2fb15avandebo@chromium.org size_t sizes[3], rowBytes[3]; 2389510ccc06bbfa5e888f66578042674be98d8ac60ctguil@chromium.org for (int i = 0; i < 3; ++i) { 2398887ede82465687355c7a1c51e4553e99b2fb15avandebo@chromium.org rowBytes[i] = yuvSizes[i].fWidth; 2408887ede82465687355c7a1c51e4553e99b2fb15avandebo@chromium.org totalSize += sizes[i] = rowBytes[i] * yuvSizes[i].fHeight; 2418887ede82465687355c7a1c51e4553e99b2fb15avandebo@chromium.org } 2428887ede82465687355c7a1c51e4553e99b2fb15avandebo@chromium.org SkAutoMalloc storage(totalSize); 2438887ede82465687355c7a1c51e4553e99b2fb15avandebo@chromium.org void* planes[3]; 2448887ede82465687355c7a1c51e4553e99b2fb15avandebo@chromium.org planes[0] = storage.get(); 2458887ede82465687355c7a1c51e4553e99b2fb15avandebo@chromium.org planes[1] = (uint8_t*)planes[0] + sizes[0]; 2468887ede82465687355c7a1c51e4553e99b2fb15avandebo@chromium.org planes[2] = (uint8_t*)planes[1] + sizes[1]; 2478887ede82465687355c7a1c51e4553e99b2fb15avandebo@chromium.org 2488887ede82465687355c7a1c51e4553e99b2fb15avandebo@chromium.org SkYUVColorSpace colorSpace; 2498887ede82465687355c7a1c51e4553e99b2fb15avandebo@chromium.org 2508887ede82465687355c7a1c51e4553e99b2fb15avandebo@chromium.org // Get the YUV planes 2518887ede82465687355c7a1c51e4553e99b2fb15avandebo@chromium.org if (!pixelRef->getYUV8Planes(yuvSizes, planes, rowBytes, &colorSpace)) { 2528887ede82465687355c7a1c51e4553e99b2fb15avandebo@chromium.org return NULL; 2538887ede82465687355c7a1c51e4553e99b2fb15avandebo@chromium.org } 2549fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org 2559fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org GrSurfaceDesc yuvDesc; 2569fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org yuvDesc.fConfig = kAlpha_8_GrPixelConfig; 2579fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org SkAutoTUnref<GrTexture> yuvTextures[3]; 2589fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org for (int i = 0; i < 3; ++i) { 2599fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org yuvDesc.fWidth = yuvSizes[i].fWidth; 2609fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org yuvDesc.fHeight = yuvSizes[i].fHeight; 2619fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org yuvTextures[i].reset( 2629fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org ctx->refScratchTexture(yuvDesc, GrContext::kApprox_ScratchTexMatch)); 2639fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org if (!yuvTextures[i] || 2649fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org !yuvTextures[i]->writePixels(0, 0, yuvDesc.fWidth, yuvDesc.fHeight, 2659fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org yuvDesc.fConfig, planes[i], rowBytes[i])) { 2669fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org return NULL; 2673e7b280b720ae202db6561f31d862990a7be32d9vandebo@chromium.org } 2689fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org } 2699fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org 2709fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org GrSurfaceDesc rtDesc = desc; 2719fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org rtDesc.fFlags = rtDesc.fFlags | 2729fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org kRenderTarget_GrSurfaceFlag | 2739fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org kNoStencil_GrSurfaceFlag; 2749fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org 2759fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org GrTexture* result = sk_gr_allocate_texture(ctx, cache, params, bm, rtDesc, NULL, 0); 2769fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org 2779fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org GrRenderTarget* renderTarget = result ? result->asRenderTarget() : NULL; 2789fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org if (renderTarget) { 2799fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org SkAutoTUnref<GrFragmentProcessor> yuvToRgbProcessor( 2809fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org GrYUVtoRGBEffect::Create(yuvTextures[0], yuvTextures[1], yuvTextures[2], colorSpace)); 281769fa6a013baca6d7404e2bf096a34a7e3635fa5ctguil@chromium.org GrPaint paint; 2829fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org paint.addColorProcessor(yuvToRgbProcessor); 2839fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org SkRect r = SkRect::MakeWH(SkIntToScalar(yuvSizes[0].fWidth), 2849fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org SkIntToScalar(yuvSizes[0].fHeight)); 2859fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org GrContext::AutoRenderTarget autoRT(ctx, renderTarget); 2869fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org GrContext::AutoClip ac(ctx, GrContext::AutoClip::kWideOpen_InitialClip); 2879fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org ctx->drawRect(paint, SkMatrix::I(), r); 2889fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org } else { 2899fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org SkSafeSetNull(result); 2909fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org } 2919fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org 2929fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org return result; 2939fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org} 2949fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org 2959fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.orgstatic GrTexture* sk_gr_create_bitmap_texture(GrContext* ctx, 2969fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org bool cache, 2979fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org const GrTextureParams* params, 2989fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org const SkBitmap& origBitmap) { 2999fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org SkBitmap tmpBitmap; 3009fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org 3019fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org const SkBitmap* bitmap = &origBitmap; 3029fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org 3039fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org GrSurfaceDesc desc; 3049fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org generate_bitmap_texture_desc(*bitmap, &desc); 3059fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org 3069fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org if (kIndex_8_SkColorType == bitmap->colorType()) { 3079fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org // build_compressed_data doesn't do npot->pot expansion 3089fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org // and paletted textures can't be sub-updated 3099fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org if (cache && ctx->supportsIndex8PixelConfig(params, bitmap->width(), bitmap->height())) { 3109fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org size_t imageSize = GrCompressedFormatDataSize(kIndex_8_GrPixelConfig, 3119fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org bitmap->width(), bitmap->height()); 3129fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org SkAutoMalloc storage(imageSize); 3139fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org build_index8_data(storage.get(), origBitmap); 3149fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org 3159fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org // our compressed data will be trimmed, so pass width() for its 3169fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org // "rowBytes", since they are the same now. 3179fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org return sk_gr_allocate_texture(ctx, cache, params, origBitmap, 3189fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org desc, storage.get(), bitmap->width()); 3199fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org } else { 3209fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org origBitmap.copyTo(&tmpBitmap, kN32_SkColorType); 3219fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org // now bitmap points to our temp, which has been promoted to 32bits 3229fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org bitmap = &tmpBitmap; 3239fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org desc.fConfig = SkImageInfo2GrPixelConfig(bitmap->info()); 3249fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org } 3259fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org } 3269fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org 3279fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org // Is this an ETC1 encoded texture? 3289fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org#ifndef SK_IGNORE_ETC1_SUPPORT 3299fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org else if ( 3309fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org // We do not support scratch ETC1 textures, hence they should all be at least 3319fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org // trying to go to the cache. 3329fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org cache 3339fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org // Make sure that the underlying device supports ETC1 textures before we go ahead 3349fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org // and check the data. 3359fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org && ctx->getGpu()->caps()->isConfigTexturable(kETC1_GrPixelConfig) 3369fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org // If the bitmap had compressed data and was then uncompressed, it'll still return 3379fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org // compressed data on 'refEncodedData' and upload it. Probably not good, since if 3389fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org // the bitmap has available pixels, then they might not be what the decompressed 3399fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org // data is. 3409fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org && !(bitmap->readyToDraw())) { 3419fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org GrTexture *texture = load_etc1_texture(ctx, cache, params, *bitmap, desc); 3429fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org if (texture) { 3439fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org return texture; 3449fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org } 3459fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org } 3469fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org#endif // SK_IGNORE_ETC1_SUPPORT 3479fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org 3489fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org else { 3499fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org GrTexture *texture = load_yuv_texture(ctx, cache, params, *bitmap, desc); 3509fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org if (texture) { 3519fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org return texture; 3529fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org } 3539fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org } 3549fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org SkAutoLockPixels alp(*bitmap); 3559fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org if (!bitmap->readyToDraw()) { 3569fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org return NULL; 3579fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org } 3589fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org 3599fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org return sk_gr_allocate_texture(ctx, cache, params, origBitmap, desc, 3609fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org bitmap->getPixels(), bitmap->rowBytes()); 3619fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org} 3629fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org 3639fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.orgbool GrIsBitmapInCache(const GrContext* ctx, 3649fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org const SkBitmap& bitmap, 3659fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org const GrTextureParams* params) { 3669fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org GrCacheID cacheID; 3679fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org generate_bitmap_cache_id(bitmap, &cacheID); 3689fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org 3699fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org GrSurfaceDesc desc; 3709fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org generate_bitmap_texture_desc(bitmap, &desc); 3719fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org return ctx->isTextureInCache(desc, cacheID, params); 3729fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org} 3739fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org 3749fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.orgGrTexture* GrRefCachedBitmapTexture(GrContext* ctx, 3759fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org const SkBitmap& bitmap, 3769fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org const GrTextureParams* params) { 3779fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org GrTexture* result = NULL; 3789fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org 3799fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org bool cache = !bitmap.isVolatile(); 3809fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org 3819fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org if (cache) { 3829fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org // If the bitmap isn't changing try to find a cached copy first. 3839fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org 3849fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org GrCacheID cacheID; 3859fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org generate_bitmap_cache_id(bitmap, &cacheID); 3869fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org 3879fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org GrSurfaceDesc desc; 3889fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org generate_bitmap_texture_desc(bitmap, &desc); 3899fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org 3909fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org result = ctx->findAndRefTexture(desc, cacheID, params); 3919fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org } 3929fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org if (NULL == result) { 3939fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org result = sk_gr_create_bitmap_texture(ctx, cache, params, bitmap); 3949fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org } 3959fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org if (NULL == result) { 3966112c215fbdd53388e64ece36e6c7bba0fe3a451vandebo@chromium.org SkDebugf("---- failed to create texture for cache [%d %d]\n", 3979fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org bitmap.width(), bitmap.height()); 3989fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org } 3999fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org return result; 4009fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org} 4019fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org 4029fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org/////////////////////////////////////////////////////////////////////////////// 4039fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org 4049fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org// alphatype is ignore for now, but if GrPixelConfig is expanded to encompass 4059fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org// alpha info, that will be considered. 4069fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.orgGrPixelConfig SkImageInfo2GrPixelConfig(SkColorType ct, SkAlphaType) { 4079fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org switch (ct) { 4089fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org case kUnknown_SkColorType: 4099fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org return kUnknown_GrPixelConfig; 4109fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org case kAlpha_8_SkColorType: 4119fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org return kAlpha_8_GrPixelConfig; 4129fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org case kRGB_565_SkColorType: 4139fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org return kRGB_565_GrPixelConfig; 4149fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org case kARGB_4444_SkColorType: 4159fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org return kRGBA_4444_GrPixelConfig; 4169fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org case kRGBA_8888_SkColorType: 4179fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org return kRGBA_8888_GrPixelConfig; 4189fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org case kBGRA_8888_SkColorType: 4199fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org return kBGRA_8888_GrPixelConfig; 4209b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org case kIndex_8_SkColorType: 4219859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org return kIndex_8_GrPixelConfig; 4229859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org } 423e97f0856a8044866b12527819d14cdfbcdfd96f2bsalomon@google.com SkASSERT(0); // shouldn't get here 424e97f0856a8044866b12527819d14cdfbcdfd96f2bsalomon@google.com return kUnknown_GrPixelConfig; 425e97f0856a8044866b12527819d14cdfbcdfd96f2bsalomon@google.com} 426e97f0856a8044866b12527819d14cdfbcdfd96f2bsalomon@google.com 427e97f0856a8044866b12527819d14cdfbcdfd96f2bsalomon@google.combool GrPixelConfig2ColorType(GrPixelConfig config, SkColorType* ctOut) { 428e97f0856a8044866b12527819d14cdfbcdfd96f2bsalomon@google.com SkColorType ct; 429e97f0856a8044866b12527819d14cdfbcdfd96f2bsalomon@google.com switch (config) { 430e97f0856a8044866b12527819d14cdfbcdfd96f2bsalomon@google.com case kAlpha_8_GrPixelConfig: 431e97f0856a8044866b12527819d14cdfbcdfd96f2bsalomon@google.com ct = kAlpha_8_SkColorType; 432b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org break; 433b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org case kIndex_8_GrPixelConfig: 434b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org ct = kIndex_8_SkColorType; 435b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org break; 436b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org case kRGB_565_GrPixelConfig: 437b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org ct = kRGB_565_SkColorType; 438b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org break; 439b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org case kRGBA_4444_GrPixelConfig: 44013d14a9dbd2cf0a9654045cc967e92626690631avandebo@chromium.org ct = kARGB_4444_SkColorType; 441b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org break; 44213d14a9dbd2cf0a9654045cc967e92626690631avandebo@chromium.org case kRGBA_8888_GrPixelConfig: 44313d14a9dbd2cf0a9654045cc967e92626690631avandebo@chromium.org ct = kRGBA_8888_SkColorType; 444b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org break; 445b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org case kBGRA_8888_GrPixelConfig: 446b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org ct = kBGRA_8888_SkColorType; 447b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org break; 448b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org default: 44913d14a9dbd2cf0a9654045cc967e92626690631avandebo@chromium.org return false; 45013d14a9dbd2cf0a9654045cc967e92626690631avandebo@chromium.org } 45113d14a9dbd2cf0a9654045cc967e92626690631avandebo@chromium.org if (ctOut) { 452b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org *ctOut = ct; 453b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org } 454b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org return true; 455b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org} 456b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org 457b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org/////////////////////////////////////////////////////////////////////////////// 45813d14a9dbd2cf0a9654045cc967e92626690631avandebo@chromium.org 459b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.orgvoid SkPaint2GrPaintNoShader(GrContext* context, const SkPaint& skPaint, GrColor paintColor, 460b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org bool constantColor, GrPaint* grPaint) { 461b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org 462b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org grPaint->setDither(skPaint.isDither()); 463b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org grPaint->setAntiAlias(skPaint.isAntiAlias()); 464b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org 465b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org SkXfermode* mode = skPaint.getXfermode(); 466b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org GrFragmentProcessor* fragmentProcessor = NULL; 467b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org GrXPFactory* xpFactory = NULL; 468b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org if (SkXfermode::AsFragmentProcessorOrXPFactory(mode, &fragmentProcessor, &xpFactory)) { 469b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org if (fragmentProcessor) { 470b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org SkASSERT(NULL == xpFactory); 471b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org grPaint->addColorProcessor(fragmentProcessor)->unref(); 472b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org xpFactory = GrPorterDuffXPFactory::Create(SkXfermode::kSrc_Mode); 473b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org } 474b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org } else { 475b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org // Fall back to src-over 476b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org xpFactory = GrPorterDuffXPFactory::Create(SkXfermode::kSrcOver_Mode); 477b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org } 478b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org SkASSERT(xpFactory); 479b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org grPaint->setXPFactory(xpFactory)->unref(); 480b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org 481b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org //set the color of the paint to the one of the parameter 4829b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org grPaint->setColor(paintColor); 4839b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org 484152612938020fa46999f33668027d5bc0f7afd18ctguil@chromium.org SkColorFilter* colorFilter = skPaint.getColorFilter(); 485a0c7edbb0804144ab320951db5c741eea247fc0fvandebo@chromium.org if (colorFilter) { 486f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com // if the source color is a constant then apply the filter here once rather than per pixel 487a0c7edbb0804144ab320951db5c741eea247fc0fvandebo@chromium.org // in a shader. 488a0c7edbb0804144ab320951db5c741eea247fc0fvandebo@chromium.org if (constantColor) { 489a0c7edbb0804144ab320951db5c741eea247fc0fvandebo@chromium.org SkColor filtered = colorFilter->filterColor(skPaint.getColor()); 490a0c7edbb0804144ab320951db5c741eea247fc0fvandebo@chromium.org grPaint->setColor(SkColor2GrColor(filtered)); 491a0c7edbb0804144ab320951db5c741eea247fc0fvandebo@chromium.org } else { 492a0c7edbb0804144ab320951db5c741eea247fc0fvandebo@chromium.org SkAutoTUnref<GrFragmentProcessor> fp(colorFilter->asFragmentProcessor(context)); 493a0c7edbb0804144ab320951db5c741eea247fc0fvandebo@chromium.org if (fp.get()) { 494a0c7edbb0804144ab320951db5c741eea247fc0fvandebo@chromium.org grPaint->addColorProcessor(fp); 495a0c7edbb0804144ab320951db5c741eea247fc0fvandebo@chromium.org } 496a0c7edbb0804144ab320951db5c741eea247fc0fvandebo@chromium.org } 497a0c7edbb0804144ab320951db5c741eea247fc0fvandebo@chromium.org } 498a0c7edbb0804144ab320951db5c741eea247fc0fvandebo@chromium.org 499a0c7edbb0804144ab320951db5c741eea247fc0fvandebo@chromium.org#ifndef SK_IGNORE_GPU_DITHER 500a0c7edbb0804144ab320951db5c741eea247fc0fvandebo@chromium.org // If the dither flag is set, then we need to see if the underlying context 501a0c7edbb0804144ab320951db5c741eea247fc0fvandebo@chromium.org // supports it. If not, then install a dither effect. 502f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com if (skPaint.isDither() && grPaint->numColorStages() > 0) { 503f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com // What are we rendering into? 504f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com const GrRenderTarget *target = context->getRenderTarget(); 505152612938020fa46999f33668027d5bc0f7afd18ctguil@chromium.org SkASSERT(target); 50675f97e452e8f2ee55cd2b283df7d7734f48bc2bfvandebo@chromium.org 507af951c9bc4cbb6e60b430194fe5127ebe99c53fbreed@google.com // Suspect the dithering flag has no effect on these configs, otherwise 508152612938020fa46999f33668027d5bc0f7afd18ctguil@chromium.org // fall back on setting the appropriate state. 5099fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org if (target->config() == kRGBA_8888_GrPixelConfig || 5108dcf74f27690476193f5d4ca34fba2e87ca7c98dctguil@chromium.org target->config() == kBGRA_8888_GrPixelConfig) { 5118dcf74f27690476193f5d4ca34fba2e87ca7c98dctguil@chromium.org // The dither flag is set and the target is likely 51277bcaa324a574584331322d98768582d9232f7fcvandebo@chromium.org // not going to be dithered by the GPU. 513a0c7edbb0804144ab320951db5c741eea247fc0fvandebo@chromium.org SkAutoTUnref<GrFragmentProcessor> fp(GrDitherEffect::Create()); 514a0c7edbb0804144ab320951db5c741eea247fc0fvandebo@chromium.org if (fp.get()) { 515152612938020fa46999f33668027d5bc0f7afd18ctguil@chromium.org grPaint->addColorProcessor(fp); 51677bcaa324a574584331322d98768582d9232f7fcvandebo@chromium.org grPaint->setDither(false); 51777bcaa324a574584331322d98768582d9232f7fcvandebo@chromium.org } 51877bcaa324a574584331322d98768582d9232f7fcvandebo@chromium.org } 519a0c7edbb0804144ab320951db5c741eea247fc0fvandebo@chromium.org } 520a0c7edbb0804144ab320951db5c741eea247fc0fvandebo@chromium.org#endif 521a0c7edbb0804144ab320951db5c741eea247fc0fvandebo@chromium.org} 522a0c7edbb0804144ab320951db5c741eea247fc0fvandebo@chromium.org 523a0c7edbb0804144ab320951db5c741eea247fc0fvandebo@chromium.orgvoid SkPaint2GrPaintShader(GrContext* context, const SkPaint& skPaint, const SkMatrix& viewM, 524a0c7edbb0804144ab320951db5c741eea247fc0fvandebo@chromium.org bool constantColor, GrPaint* grPaint) { 525a0c7edbb0804144ab320951db5c741eea247fc0fvandebo@chromium.org SkShader* shader = skPaint.getShader(); 526a0c7edbb0804144ab320951db5c741eea247fc0fvandebo@chromium.org if (NULL == shader) { 527a0c7edbb0804144ab320951db5c741eea247fc0fvandebo@chromium.org SkPaint2GrPaintNoShader(context, skPaint, SkColor2GrColor(skPaint.getColor()), 528af951c9bc4cbb6e60b430194fe5127ebe99c53fbreed@google.com constantColor, grPaint); 529a0c7edbb0804144ab320951db5c741eea247fc0fvandebo@chromium.org return; 530a0c7edbb0804144ab320951db5c741eea247fc0fvandebo@chromium.org } 531a0c7edbb0804144ab320951db5c741eea247fc0fvandebo@chromium.org 532a0c7edbb0804144ab320951db5c741eea247fc0fvandebo@chromium.org GrColor paintColor = SkColor2GrColor(skPaint.getColor()); 5338dcf74f27690476193f5d4ca34fba2e87ca7c98dctguil@chromium.org 5348dcf74f27690476193f5d4ca34fba2e87ca7c98dctguil@chromium.org // Start a new block here in order to preserve our context state after calling 535a0c7edbb0804144ab320951db5c741eea247fc0fvandebo@chromium.org // asFragmentProcessor(). Since these calls get passed back to the client, we don't really 53677bcaa324a574584331322d98768582d9232f7fcvandebo@chromium.org // want them messing around with the context. 53777bcaa324a574584331322d98768582d9232f7fcvandebo@chromium.org { 53877bcaa324a574584331322d98768582d9232f7fcvandebo@chromium.org // SkShader::asFragmentProcessor() may do offscreen rendering. Save off the current RT, 53977bcaa324a574584331322d98768582d9232f7fcvandebo@chromium.org // and clip 5409859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org GrContext::AutoRenderTarget art(context, NULL); 54177bcaa324a574584331322d98768582d9232f7fcvandebo@chromium.org GrContext::AutoClip ac(context, GrContext::AutoClip::kWideOpen_InitialClip); 54277bcaa324a574584331322d98768582d9232f7fcvandebo@chromium.org 54377bcaa324a574584331322d98768582d9232f7fcvandebo@chromium.org // Allow the shader to modify paintColor and also create an effect to be installed as 54477bcaa324a574584331322d98768582d9232f7fcvandebo@chromium.org // the first color effect on the GrPaint. 5459fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org GrFragmentProcessor* fp = NULL; 546b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org if (shader->asFragmentProcessor(context, skPaint, viewM, NULL, &paintColor, &fp) && fp) { 5478dcf74f27690476193f5d4ca34fba2e87ca7c98dctguil@chromium.org grPaint->addColorProcessor(fp)->unref(); 5488dcf74f27690476193f5d4ca34fba2e87ca7c98dctguil@chromium.org constantColor = false; 5499859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org } 5509859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org } 5519859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org 5529859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org // The grcolor is automatically set when calling asFragmentProcessor. 5539b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org // If the shader can be seen as an effect it returns true and adds its effect to the grpaint. 5549b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org SkPaint2GrPaintNoShader(context, skPaint, paintColor, constantColor, grPaint); 5559859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org} 5569b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org