1bf2768bab9f3b21c03a8f9a75dc891231d5857ccsenorblanco@chromium.org/* 2bf2768bab9f3b21c03a8f9a75dc891231d5857ccsenorblanco@chromium.org * Copyright 2012 The Android Open Source Project 3bf2768bab9f3b21c03a8f9a75dc891231d5857ccsenorblanco@chromium.org * 4bf2768bab9f3b21c03a8f9a75dc891231d5857ccsenorblanco@chromium.org * Use of this source code is governed by a BSD-style license that can be 5bf2768bab9f3b21c03a8f9a75dc891231d5857ccsenorblanco@chromium.org * found in the LICENSE file. 6bf2768bab9f3b21c03a8f9a75dc891231d5857ccsenorblanco@chromium.org */ 7bf2768bab9f3b21c03a8f9a75dc891231d5857ccsenorblanco@chromium.org 8bf2768bab9f3b21c03a8f9a75dc891231d5857ccsenorblanco@chromium.org#include "SkImageFilter.h" 99f25de79009ce721aa13abe71c38179d5a6710e2senorblanco@chromium.org 109f25de79009ce721aa13abe71c38179d5a6710e2senorblanco@chromium.org#include "SkBitmap.h" 11118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org#include "SkDevice.h" 128b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkReadBuffer.h" 138b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkWriteBuffer.h" 14bf2768bab9f3b21c03a8f9a75dc891231d5857ccsenorblanco@chromium.org#include "SkRect.h" 15f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org#include "SkTDynamicHash.h" 16c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org#include "SkValidationUtils.h" 17d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org#if SK_SUPPORT_GPU 18d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org#include "GrContext.h" 196aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org#include "SkGrPixelRef.h" 206aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org#include "SkGr.h" 21d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org#endif 22bf2768bab9f3b21c03a8f9a75dc891231d5857ccsenorblanco@chromium.org 231a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.orgSkImageFilter::Cache* gExternalCache; 241a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org 25b295fb6ff3222453912dfcb7a1ea5184d40014b5senorblanco@chromium.orgSkImageFilter::SkImageFilter(int inputCount, SkImageFilter** inputs, const CropRect* cropRect) 26194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org : fInputCount(inputCount), 27194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org fInputs(new SkImageFilter*[inputCount]), 28b295fb6ff3222453912dfcb7a1ea5184d40014b5senorblanco@chromium.org fCropRect(cropRect ? *cropRect : CropRect(SkRect(), 0x0)) { 298d21f6c7a9d0cf4f87d77c235c6da7203620c7e5senorblanco@chromium.org for (int i = 0; i < inputCount; ++i) { 309f25de79009ce721aa13abe71c38179d5a6710e2senorblanco@chromium.org fInputs[i] = inputs[i]; 319f25de79009ce721aa13abe71c38179d5a6710e2senorblanco@chromium.org SkSafeRef(fInputs[i]); 329f25de79009ce721aa13abe71c38179d5a6710e2senorblanco@chromium.org } 339f25de79009ce721aa13abe71c38179d5a6710e2senorblanco@chromium.org} 349f25de79009ce721aa13abe71c38179d5a6710e2senorblanco@chromium.org 35b295fb6ff3222453912dfcb7a1ea5184d40014b5senorblanco@chromium.orgSkImageFilter::SkImageFilter(SkImageFilter* input, const CropRect* cropRect) 36194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org : fInputCount(1), 37194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org fInputs(new SkImageFilter*[1]), 38b295fb6ff3222453912dfcb7a1ea5184d40014b5senorblanco@chromium.org fCropRect(cropRect ? *cropRect : CropRect(SkRect(), 0x0)) { 39c2e8cef4792b478547973d312b26fff4aab7c729senorblanco@chromium.org fInputs[0] = input; 40c2e8cef4792b478547973d312b26fff4aab7c729senorblanco@chromium.org SkSafeRef(fInputs[0]); 41c2e8cef4792b478547973d312b26fff4aab7c729senorblanco@chromium.org} 42c2e8cef4792b478547973d312b26fff4aab7c729senorblanco@chromium.org 43b295fb6ff3222453912dfcb7a1ea5184d40014b5senorblanco@chromium.orgSkImageFilter::SkImageFilter(SkImageFilter* input1, SkImageFilter* input2, const CropRect* cropRect) 44194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org : fInputCount(2), fInputs(new SkImageFilter*[2]), 45b295fb6ff3222453912dfcb7a1ea5184d40014b5senorblanco@chromium.org fCropRect(cropRect ? *cropRect : CropRect(SkRect(), 0x0)) { 46c2e8cef4792b478547973d312b26fff4aab7c729senorblanco@chromium.org fInputs[0] = input1; 47c2e8cef4792b478547973d312b26fff4aab7c729senorblanco@chromium.org fInputs[1] = input2; 48c2e8cef4792b478547973d312b26fff4aab7c729senorblanco@chromium.org SkSafeRef(fInputs[0]); 49c2e8cef4792b478547973d312b26fff4aab7c729senorblanco@chromium.org SkSafeRef(fInputs[1]); 509f25de79009ce721aa13abe71c38179d5a6710e2senorblanco@chromium.org} 519f25de79009ce721aa13abe71c38179d5a6710e2senorblanco@chromium.org 529f25de79009ce721aa13abe71c38179d5a6710e2senorblanco@chromium.orgSkImageFilter::~SkImageFilter() { 538d21f6c7a9d0cf4f87d77c235c6da7203620c7e5senorblanco@chromium.org for (int i = 0; i < fInputCount; i++) { 549f25de79009ce721aa13abe71c38179d5a6710e2senorblanco@chromium.org SkSafeUnref(fInputs[i]); 559f25de79009ce721aa13abe71c38179d5a6710e2senorblanco@chromium.org } 569f25de79009ce721aa13abe71c38179d5a6710e2senorblanco@chromium.org delete[] fInputs; 579f25de79009ce721aa13abe71c38179d5a6710e2senorblanco@chromium.org} 589f25de79009ce721aa13abe71c38179d5a6710e2senorblanco@chromium.org 598b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgSkImageFilter::SkImageFilter(int inputCount, SkReadBuffer& buffer) { 60ce33d60187718e7bb01944ee130c9f5d9fb335eccommit-bot@chromium.org fInputCount = buffer.readInt(); 61c84728d72a47415929464c5cf062300d86a91246commit-bot@chromium.org if (buffer.validate((fInputCount >= 0) && ((inputCount < 0) || (fInputCount == inputCount)))) { 62ce33d60187718e7bb01944ee130c9f5d9fb335eccommit-bot@chromium.org fInputs = new SkImageFilter*[fInputCount]; 63ce33d60187718e7bb01944ee130c9f5d9fb335eccommit-bot@chromium.org for (int i = 0; i < fInputCount; i++) { 64ce33d60187718e7bb01944ee130c9f5d9fb335eccommit-bot@chromium.org if (buffer.readBool()) { 65ce33d60187718e7bb01944ee130c9f5d9fb335eccommit-bot@chromium.org fInputs[i] = buffer.readImageFilter(); 66ce33d60187718e7bb01944ee130c9f5d9fb335eccommit-bot@chromium.org } else { 67ce33d60187718e7bb01944ee130c9f5d9fb335eccommit-bot@chromium.org fInputs[i] = NULL; 68ce33d60187718e7bb01944ee130c9f5d9fb335eccommit-bot@chromium.org } 69c2e9db30d393862bd3485cfe57b4ac06433f2f32commit-bot@chromium.org if (!buffer.isValid()) { 70c2e9db30d393862bd3485cfe57b4ac06433f2f32commit-bot@chromium.org fInputCount = i; // Do not use fInputs past that point in the destructor 71c2e9db30d393862bd3485cfe57b4ac06433f2f32commit-bot@chromium.org break; 72c2e9db30d393862bd3485cfe57b4ac06433f2f32commit-bot@chromium.org } 73ce33d60187718e7bb01944ee130c9f5d9fb335eccommit-bot@chromium.org } 74ce33d60187718e7bb01944ee130c9f5d9fb335eccommit-bot@chromium.org SkRect rect; 75ce33d60187718e7bb01944ee130c9f5d9fb335eccommit-bot@chromium.org buffer.readRect(&rect); 76c2e9db30d393862bd3485cfe57b4ac06433f2f32commit-bot@chromium.org if (buffer.isValid() && buffer.validate(SkIsValidRect(rect))) { 77ce33d60187718e7bb01944ee130c9f5d9fb335eccommit-bot@chromium.org uint32_t flags = buffer.readUInt(); 78ce33d60187718e7bb01944ee130c9f5d9fb335eccommit-bot@chromium.org fCropRect = CropRect(rect, flags); 799f25de79009ce721aa13abe71c38179d5a6710e2senorblanco@chromium.org } 80ce33d60187718e7bb01944ee130c9f5d9fb335eccommit-bot@chromium.org } else { 81ce33d60187718e7bb01944ee130c9f5d9fb335eccommit-bot@chromium.org fInputCount = 0; 82ce33d60187718e7bb01944ee130c9f5d9fb335eccommit-bot@chromium.org fInputs = NULL; 839f25de79009ce721aa13abe71c38179d5a6710e2senorblanco@chromium.org } 849f25de79009ce721aa13abe71c38179d5a6710e2senorblanco@chromium.org} 859f25de79009ce721aa13abe71c38179d5a6710e2senorblanco@chromium.org 868b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgvoid SkImageFilter::flatten(SkWriteBuffer& buffer) const { 878d21f6c7a9d0cf4f87d77c235c6da7203620c7e5senorblanco@chromium.org buffer.writeInt(fInputCount); 888d21f6c7a9d0cf4f87d77c235c6da7203620c7e5senorblanco@chromium.org for (int i = 0; i < fInputCount; i++) { 899f25de79009ce721aa13abe71c38179d5a6710e2senorblanco@chromium.org SkImageFilter* input = getInput(i); 909f25de79009ce721aa13abe71c38179d5a6710e2senorblanco@chromium.org buffer.writeBool(input != NULL); 919f25de79009ce721aa13abe71c38179d5a6710e2senorblanco@chromium.org if (input != NULL) { 929f25de79009ce721aa13abe71c38179d5a6710e2senorblanco@chromium.org buffer.writeFlattenable(input); 939f25de79009ce721aa13abe71c38179d5a6710e2senorblanco@chromium.org } 949f25de79009ce721aa13abe71c38179d5a6710e2senorblanco@chromium.org } 953f1f2a3a59c43e5bce67ab98e55df45bc7c933a3senorblanco@chromium.org buffer.writeRect(fCropRect.rect()); 963f1f2a3a59c43e5bce67ab98e55df45bc7c933a3senorblanco@chromium.org buffer.writeUInt(fCropRect.flags()); 979f25de79009ce721aa13abe71c38179d5a6710e2senorblanco@chromium.org} 989f25de79009ce721aa13abe71c38179d5a6710e2senorblanco@chromium.org 99bf2768bab9f3b21c03a8f9a75dc891231d5857ccsenorblanco@chromium.orgbool SkImageFilter::filterImage(Proxy* proxy, const SkBitmap& src, 1004cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org const Context& context, 101ae761f7545d8ebf181d220169afac2056b057b8ccommit-bot@chromium.org SkBitmap* result, SkIPoint* offset) const { 102f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org Cache* cache = context.cache(); 103bf2768bab9f3b21c03a8f9a75dc891231d5857ccsenorblanco@chromium.org SkASSERT(result); 1046776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org SkASSERT(offset); 105f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org SkASSERT(cache); 106f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org if (cache->get(this, result, offset)) { 107f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org return true; 108f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org } 109bf2768bab9f3b21c03a8f9a75dc891231d5857ccsenorblanco@chromium.org /* 110bf2768bab9f3b21c03a8f9a75dc891231d5857ccsenorblanco@chromium.org * Give the proxy first shot at the filter. If it returns false, ask 111bf2768bab9f3b21c03a8f9a75dc891231d5857ccsenorblanco@chromium.org * the filter to do it. 112bf2768bab9f3b21c03a8f9a75dc891231d5857ccsenorblanco@chromium.org */ 113f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org if ((proxy && proxy->filterImage(this, src, context, result, offset)) || 114f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org this->onFilterImage(proxy, src, context, result, offset)) { 115f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org cache->set(this, *result, *offset); 116f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org return true; 117f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org } 118f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org return false; 119bf2768bab9f3b21c03a8f9a75dc891231d5857ccsenorblanco@chromium.org} 120bf2768bab9f3b21c03a8f9a75dc891231d5857ccsenorblanco@chromium.org 121bf2768bab9f3b21c03a8f9a75dc891231d5857ccsenorblanco@chromium.orgbool SkImageFilter::filterBounds(const SkIRect& src, const SkMatrix& ctm, 122c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org SkIRect* dst) const { 123bf2768bab9f3b21c03a8f9a75dc891231d5857ccsenorblanco@chromium.org SkASSERT(&src); 124bf2768bab9f3b21c03a8f9a75dc891231d5857ccsenorblanco@chromium.org SkASSERT(dst); 125bccac6cbf128147587bfc2bc1bdeb46c08175bcasenorblanco if (SkImageFilter::GetExternalCache()) { 126bccac6cbf128147587bfc2bc1bdeb46c08175bcasenorblanco /* 127bccac6cbf128147587bfc2bc1bdeb46c08175bcasenorblanco * When the external cache is active, do not intersect the saveLayer 128bccac6cbf128147587bfc2bc1bdeb46c08175bcasenorblanco * bounds with the clip bounds. This is so that the cached result 129bccac6cbf128147587bfc2bc1bdeb46c08175bcasenorblanco * is always the full size of the primitive's bounds, 130bccac6cbf128147587bfc2bc1bdeb46c08175bcasenorblanco * regardless of the clip active on first draw. 131bccac6cbf128147587bfc2bc1bdeb46c08175bcasenorblanco */ 132bccac6cbf128147587bfc2bc1bdeb46c08175bcasenorblanco *dst = SkIRect::MakeLargest(); 133bccac6cbf128147587bfc2bc1bdeb46c08175bcasenorblanco return true; 134bccac6cbf128147587bfc2bc1bdeb46c08175bcasenorblanco } 135bf2768bab9f3b21c03a8f9a75dc891231d5857ccsenorblanco@chromium.org return this->onFilterBounds(src, ctm, dst); 136bf2768bab9f3b21c03a8f9a75dc891231d5857ccsenorblanco@chromium.org} 137bf2768bab9f3b21c03a8f9a75dc891231d5857ccsenorblanco@chromium.org 138336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.orgvoid SkImageFilter::computeFastBounds(const SkRect& src, SkRect* dst) const { 139336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org if (0 == fInputCount) { 140336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org *dst = src; 141336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org return; 142336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org } 143336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org if (this->getInput(0)) { 144336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org this->getInput(0)->computeFastBounds(src, dst); 145336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org } else { 146336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org *dst = src; 147336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org } 148336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org for (int i = 1; i < fInputCount; i++) { 149336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org SkImageFilter* input = this->getInput(i); 150336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org if (input) { 151336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org SkRect bounds; 152336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org input->computeFastBounds(src, &bounds); 153336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org dst->join(bounds); 154336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org } else { 155336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org dst->join(src); 156336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org } 157336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org } 158336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org} 159336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org 1604cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.orgbool SkImageFilter::onFilterImage(Proxy*, const SkBitmap&, const Context&, 161ae761f7545d8ebf181d220169afac2056b057b8ccommit-bot@chromium.org SkBitmap*, SkIPoint*) const { 162bf2768bab9f3b21c03a8f9a75dc891231d5857ccsenorblanco@chromium.org return false; 163bf2768bab9f3b21c03a8f9a75dc891231d5857ccsenorblanco@chromium.org} 164bf2768bab9f3b21c03a8f9a75dc891231d5857ccsenorblanco@chromium.org 165bf2768bab9f3b21c03a8f9a75dc891231d5857ccsenorblanco@chromium.orgbool SkImageFilter::canFilterImageGPU() const { 1667938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org return this->asNewEffect(NULL, NULL, SkMatrix::I(), SkIRect()); 167bf2768bab9f3b21c03a8f9a75dc891231d5857ccsenorblanco@chromium.org} 168bf2768bab9f3b21c03a8f9a75dc891231d5857ccsenorblanco@chromium.org 1694cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.orgbool SkImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const Context& ctx, 170ae761f7545d8ebf181d220169afac2056b057b8ccommit-bot@chromium.org SkBitmap* result, SkIPoint* offset) const { 171d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org#if SK_SUPPORT_GPU 1726aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org SkBitmap input = src; 173d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org SkASSERT(fInputCount == 1); 174aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org SkIPoint srcOffset = SkIPoint::Make(0, 0); 1756aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org if (this->getInput(0) && 1764cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org !this->getInput(0)->getInputResultGPU(proxy, src, ctx, &input, &srcOffset)) { 177d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org return false; 178d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org } 179b8d00db075b5ea09e353508a26ef5ced50722a6ccommit-bot@chromium.org GrTexture* srcTexture = input.getTexture(); 1804e16bb2a322f2bd16cb1afd2f78c27e420a4b9dbsenorblanco@chromium.org SkIRect bounds; 181118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org if (!this->applyCropRect(ctx, proxy, input, &srcOffset, &bounds, &input)) { 1824e16bb2a322f2bd16cb1afd2f78c27e420a4b9dbsenorblanco@chromium.org return false; 1834e16bb2a322f2bd16cb1afd2f78c27e420a4b9dbsenorblanco@chromium.org } 1844e16bb2a322f2bd16cb1afd2f78c27e420a4b9dbsenorblanco@chromium.org SkRect srcRect = SkRect::Make(bounds); 1854e16bb2a322f2bd16cb1afd2f78c27e420a4b9dbsenorblanco@chromium.org SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height()); 186d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org GrContext* context = srcTexture->getContext(); 187d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org 188d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org GrTextureDesc desc; 189d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org desc.fFlags = kRenderTarget_GrTextureFlagBit, 1904e16bb2a322f2bd16cb1afd2f78c27e420a4b9dbsenorblanco@chromium.org desc.fWidth = bounds.width(); 1914e16bb2a322f2bd16cb1afd2f78c27e420a4b9dbsenorblanco@chromium.org desc.fHeight = bounds.height(); 192d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org desc.fConfig = kRGBA_8888_GrPixelConfig; 193d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org 194d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org GrAutoScratchTexture dst(context, desc); 195d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org GrContext::AutoMatrix am; 196d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org am.setIdentity(context); 197d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org GrContext::AutoRenderTarget art(context, dst.texture()->asRenderTarget()); 1984e16bb2a322f2bd16cb1afd2f78c27e420a4b9dbsenorblanco@chromium.org GrContext::AutoClip acs(context, dstRect); 199d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org GrEffectRef* effect; 200aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org offset->fX = bounds.left(); 201aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org offset->fY = bounds.top(); 202aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org bounds.offset(-srcOffset); 2034cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org SkMatrix matrix(ctx.ctm()); 204fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org matrix.postTranslate(SkIntToScalar(-bounds.left()), SkIntToScalar(-bounds.top())); 2057938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org this->asNewEffect(&effect, srcTexture, matrix, bounds); 206d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org SkASSERT(effect); 207d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org SkAutoUnref effectRef(effect); 208d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org GrPaint paint; 20942dacab4e7366d9f53989558cc8d045c3d065bcdcommit-bot@chromium.org paint.addColorEffect(effect); 2104e16bb2a322f2bd16cb1afd2f78c27e420a4b9dbsenorblanco@chromium.org context->drawRectToRect(paint, dstRect, srcRect); 2114e16bb2a322f2bd16cb1afd2f78c27e420a4b9dbsenorblanco@chromium.org 212d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org SkAutoTUnref<GrTexture> resultTex(dst.detach()); 2136aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org WrapTexture(resultTex, bounds.width(), bounds.height(), result); 214d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org return true; 215d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org#else 216c2594f41066102d7a8a73effd3c574142a018b9asenorblanco@chromium.org return false; 217d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org#endif 218bf2768bab9f3b21c03a8f9a75dc891231d5857ccsenorblanco@chromium.org} 219bf2768bab9f3b21c03a8f9a75dc891231d5857ccsenorblanco@chromium.org 220118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.orgbool SkImageFilter::applyCropRect(const Context& ctx, const SkBitmap& src, 221118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org const SkIPoint& srcOffset, SkIRect* bounds) const { 222118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org SkIRect srcBounds; 223118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org src.getBounds(&srcBounds); 224118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org srcBounds.offset(srcOffset); 225fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org SkRect cropRect; 226118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org ctx.ctm().mapRect(&cropRect, fCropRect.rect()); 227b295fb6ff3222453912dfcb7a1ea5184d40014b5senorblanco@chromium.org SkIRect cropRectI; 228b295fb6ff3222453912dfcb7a1ea5184d40014b5senorblanco@chromium.org cropRect.roundOut(&cropRectI); 2293f1f2a3a59c43e5bce67ab98e55df45bc7c933a3senorblanco@chromium.org uint32_t flags = fCropRect.flags(); 230118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org if (flags & CropRect::kHasLeft_CropEdge) srcBounds.fLeft = cropRectI.fLeft; 231118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org if (flags & CropRect::kHasTop_CropEdge) srcBounds.fTop = cropRectI.fTop; 232118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org if (flags & CropRect::kHasRight_CropEdge) srcBounds.fRight = cropRectI.fRight; 233118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org if (flags & CropRect::kHasBottom_CropEdge) srcBounds.fBottom = cropRectI.fBottom; 234118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org if (!srcBounds.intersect(ctx.clipBounds())) { 235118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org return false; 236118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org } 237118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org *bounds = srcBounds; 238118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org return true; 239118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org} 240118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org 241118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.orgbool SkImageFilter::applyCropRect(const Context& ctx, Proxy* proxy, const SkBitmap& src, 242118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org SkIPoint* srcOffset, SkIRect* bounds, SkBitmap* dst) const { 243118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org SkIRect srcBounds; 244118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org src.getBounds(&srcBounds); 245118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org srcBounds.offset(*srcOffset); 246118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org SkRect cropRect; 247118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org ctx.ctm().mapRect(&cropRect, fCropRect.rect()); 248118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org SkIRect cropRectI; 249118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org cropRect.roundOut(&cropRectI); 250118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org uint32_t flags = fCropRect.flags(); 251118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org *bounds = srcBounds; 252118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org if (flags & CropRect::kHasLeft_CropEdge) bounds->fLeft = cropRectI.fLeft; 253118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org if (flags & CropRect::kHasTop_CropEdge) bounds->fTop = cropRectI.fTop; 254118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org if (flags & CropRect::kHasRight_CropEdge) bounds->fRight = cropRectI.fRight; 255118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org if (flags & CropRect::kHasBottom_CropEdge) bounds->fBottom = cropRectI.fBottom; 256118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org if (!bounds->intersect(ctx.clipBounds())) { 257118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org return false; 258118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org } 259118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org if (srcBounds.contains(*bounds)) { 260118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org *dst = src; 261118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org return true; 262118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org } else { 263118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(bounds->width(), bounds->height())); 264118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org if (!device) { 265118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org return false; 266118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org } 267118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org SkCanvas canvas(device); 268118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org canvas.clear(0x00000000); 269118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org canvas.drawBitmap(src, srcOffset->x() - bounds->x(), srcOffset->y() - bounds->y()); 270118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org *srcOffset = SkIPoint::Make(bounds->x(), bounds->y()); 271118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org *dst = device->accessBitmap(false); 272118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org return true; 273118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org } 274194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org} 275194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org 276bf2768bab9f3b21c03a8f9a75dc891231d5857ccsenorblanco@chromium.orgbool SkImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm, 277c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org SkIRect* dst) const { 278c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org if (fInputCount < 1) { 279c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org return false; 280c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org } 281c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org 282c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org SkIRect bounds; 283c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org for (int i = 0; i < fInputCount; ++i) { 284c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org SkImageFilter* filter = this->getInput(i); 285c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org SkIRect rect = src; 286c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org if (filter && !filter->filterBounds(src, ctm, &rect)) { 287c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org return false; 288c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org } 289c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org if (0 == i) { 290c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org bounds = rect; 291c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org } else { 292c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org bounds.join(rect); 293c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org } 294c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org } 295c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org 296c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org // don't modify dst until now, so we don't accidentally change it in the 297c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org // loop, but then return false on the next filter. 298c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org *dst = bounds; 299bf2768bab9f3b21c03a8f9a75dc891231d5857ccsenorblanco@chromium.org return true; 300bf2768bab9f3b21c03a8f9a75dc891231d5857ccsenorblanco@chromium.org} 301bf2768bab9f3b21c03a8f9a75dc891231d5857ccsenorblanco@chromium.org 3027938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.orgbool SkImageFilter::asNewEffect(GrEffectRef**, GrTexture*, const SkMatrix&, const SkIRect&) const { 303bf2768bab9f3b21c03a8f9a75dc891231d5857ccsenorblanco@chromium.org return false; 304bf2768bab9f3b21c03a8f9a75dc891231d5857ccsenorblanco@chromium.org} 3058d21f6c7a9d0cf4f87d77c235c6da7203620c7e5senorblanco@chromium.org 306a1c511b8704c6c266b90860a4c68f30ca7514f9bsugoi@google.combool SkImageFilter::asColorFilter(SkColorFilter**) const { 307a1c511b8704c6c266b90860a4c68f30ca7514f9bsugoi@google.com return false; 3088d21f6c7a9d0cf4f87d77c235c6da7203620c7e5senorblanco@chromium.org} 3096aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org 3101a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.orgvoid SkImageFilter::SetExternalCache(Cache* cache) { 3111a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org SkRefCnt_SafeAssign(gExternalCache, cache); 3121a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org} 3131a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org 3141a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.orgSkImageFilter::Cache* SkImageFilter::GetExternalCache() { 3151a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org return gExternalCache; 3161a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org} 3171a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org 3186aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org#if SK_SUPPORT_GPU 3196aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org 3206aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.orgvoid SkImageFilter::WrapTexture(GrTexture* texture, int width, int height, SkBitmap* result) { 3216aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org SkImageInfo info = SkImageInfo::MakeN32Premul(width, height); 322a3264e53ee3f3c5d6a2c813df7e44b5b96d207f2commit-bot@chromium.org result->setInfo(info); 3236aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org result->setPixelRef(SkNEW_ARGS(SkGrPixelRef, (info, texture)))->unref(); 3246aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org} 3256aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org 3266aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.orgbool SkImageFilter::getInputResultGPU(SkImageFilter::Proxy* proxy, 3274cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org const SkBitmap& src, const Context& ctx, 3286aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org SkBitmap* result, SkIPoint* offset) const { 3296aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org // Ensure that GrContext calls under filterImage and filterImageGPU below will see an identity 3306aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org // matrix with no clip and that the matrix, clip, and render target set before this function was 3316aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org // called are restored before we return to the caller. 3326aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org GrContext* context = src.getTexture()->getContext(); 3336aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org GrContext::AutoWideOpenIdentityDraw awoid(context, NULL); 3346aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org if (this->canFilterImageGPU()) { 3354cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org return this->filterImageGPU(proxy, src, ctx, result, offset); 3366aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org } else { 3374cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org if (this->filterImage(proxy, src, ctx, result, offset)) { 3386aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org if (!result->getTexture()) { 339466f5f3e44e703ca58b43ac1c4ac3bfa0e1ff024commit-bot@chromium.org const SkImageInfo info = result->info(); 340466f5f3e44e703ca58b43ac1c4ac3bfa0e1ff024commit-bot@chromium.org if (kUnknown_SkColorType == info.colorType()) { 3416aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org return false; 3426aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org } 3436aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org GrTexture* resultTex = GrLockAndRefCachedBitmapTexture(context, *result, NULL); 3446aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org result->setPixelRef(new SkGrPixelRef(info, resultTex))->unref(); 3456aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org GrUnlockAndUnrefCachedBitmapTexture(resultTex); 3466aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org } 3476aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org return true; 3486aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org } else { 3496aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org return false; 3506aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org } 3516aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org } 3526aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org} 3536aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org#endif 354f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org 355f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.orgstatic uint32_t compute_hash(const uint32_t* data, int count) { 356f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org uint32_t hash = 0; 357f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org 358f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org for (int i = 0; i < count; ++i) { 359f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org uint32_t k = data[i]; 360f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org k *= 0xcc9e2d51; 361f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org k = (k << 15) | (k >> 17); 362f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org k *= 0x1b873593; 363f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org 364f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org hash ^= k; 365f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org hash = (hash << 13) | (hash >> 19); 366f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org hash *= 5; 367f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org hash += 0xe6546b64; 368f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org } 369f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org 370f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org // hash ^= size; 371f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org hash ^= hash >> 16; 372f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org hash *= 0x85ebca6b; 373f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org hash ^= hash >> 13; 374f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org hash *= 0xc2b2ae35; 375f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org hash ^= hash >> 16; 376f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org 377f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org return hash; 378f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org} 379f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org 380f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.orgclass CacheImpl : public SkImageFilter::Cache { 381f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.orgpublic: 382f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org explicit CacheImpl(int minChildren) : fMinChildren(minChildren) {} 383f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org virtual ~CacheImpl(); 384f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org bool get(const SkImageFilter* key, SkBitmap* result, SkIPoint* offset) SK_OVERRIDE; 385f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org void set(const SkImageFilter* key, const SkBitmap& result, const SkIPoint& offset) SK_OVERRIDE; 3861a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org void remove(const SkImageFilter* key) SK_OVERRIDE; 387f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.orgprivate: 388f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org typedef const SkImageFilter* Key; 389f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org struct Value { 390f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org Value(Key key, const SkBitmap& bitmap, const SkIPoint& offset) 391f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org : fKey(key), fBitmap(bitmap), fOffset(offset) {} 392f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org Key fKey; 393f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org SkBitmap fBitmap; 394f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org SkIPoint fOffset; 395f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org static const Key& GetKey(const Value& v) { 396f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org return v.fKey; 397f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org } 398f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org static uint32_t Hash(Key key) { 399f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org return compute_hash(reinterpret_cast<const uint32_t*>(&key), sizeof(Key) / sizeof(uint32_t)); 400f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org } 401f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org }; 402f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org SkTDynamicHash<Value, Key> fData; 403f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org int fMinChildren; 404f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org}; 405f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org 406f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.orgbool CacheImpl::get(const SkImageFilter* key, SkBitmap* result, SkIPoint* offset) { 407f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org Value* v = fData.find(key); 408f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org if (v) { 409f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org *result = v->fBitmap; 410f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org *offset = v->fOffset; 411f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org return true; 412f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org } 413f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org return false; 414f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org} 415f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org 4161a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.orgvoid CacheImpl::remove(const SkImageFilter* key) { 4171a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org Value* v = fData.find(key); 4181a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org if (v) { 4191a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org fData.remove(key); 4201a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org delete v; 4211a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org } 4221a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org} 4231a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org 424f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.orgvoid CacheImpl::set(const SkImageFilter* key, const SkBitmap& result, const SkIPoint& offset) { 425f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org if (key->getRefCnt() >= fMinChildren) { 426f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org fData.add(new Value(key, result, offset)); 427f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org } 428f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org} 429f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org 430f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.orgSkImageFilter::Cache* SkImageFilter::Cache::Create(int minChildren) { 431f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org return new CacheImpl(minChildren); 432f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org} 433f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org 434f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.orgCacheImpl::~CacheImpl() { 435f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org SkTDynamicHash<Value, Key>::Iter iter(&fData); 436f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org 437f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org while (!iter.done()) { 438f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org Value* v = &*iter; 439f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org ++iter; 440f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org delete v; 441f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org } 442f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org} 443