SkImageFilter.cpp revision 1a479e7547d4efe2d1d06fab5c9442b77ec6c954
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); 125bf2768bab9f3b21c03a8f9a75dc891231d5857ccsenorblanco@chromium.org return this->onFilterBounds(src, ctm, dst); 126bf2768bab9f3b21c03a8f9a75dc891231d5857ccsenorblanco@chromium.org} 127bf2768bab9f3b21c03a8f9a75dc891231d5857ccsenorblanco@chromium.org 128336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.orgvoid SkImageFilter::computeFastBounds(const SkRect& src, SkRect* dst) const { 129336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org if (0 == fInputCount) { 130336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org *dst = src; 131336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org return; 132336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org } 133336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org if (this->getInput(0)) { 134336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org this->getInput(0)->computeFastBounds(src, dst); 135336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org } else { 136336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org *dst = src; 137336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org } 138336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org for (int i = 1; i < fInputCount; i++) { 139336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org SkImageFilter* input = this->getInput(i); 140336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org if (input) { 141336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org SkRect bounds; 142336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org input->computeFastBounds(src, &bounds); 143336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org dst->join(bounds); 144336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org } else { 145336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org dst->join(src); 146336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org } 147336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org } 148336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org} 149336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org 1504cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.orgbool SkImageFilter::onFilterImage(Proxy*, const SkBitmap&, const Context&, 151ae761f7545d8ebf181d220169afac2056b057b8ccommit-bot@chromium.org SkBitmap*, SkIPoint*) const { 152bf2768bab9f3b21c03a8f9a75dc891231d5857ccsenorblanco@chromium.org return false; 153bf2768bab9f3b21c03a8f9a75dc891231d5857ccsenorblanco@chromium.org} 154bf2768bab9f3b21c03a8f9a75dc891231d5857ccsenorblanco@chromium.org 155bf2768bab9f3b21c03a8f9a75dc891231d5857ccsenorblanco@chromium.orgbool SkImageFilter::canFilterImageGPU() const { 1567938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org return this->asNewEffect(NULL, NULL, SkMatrix::I(), SkIRect()); 157bf2768bab9f3b21c03a8f9a75dc891231d5857ccsenorblanco@chromium.org} 158bf2768bab9f3b21c03a8f9a75dc891231d5857ccsenorblanco@chromium.org 1594cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.orgbool SkImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const Context& ctx, 160ae761f7545d8ebf181d220169afac2056b057b8ccommit-bot@chromium.org SkBitmap* result, SkIPoint* offset) const { 161d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org#if SK_SUPPORT_GPU 1626aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org SkBitmap input = src; 163d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org SkASSERT(fInputCount == 1); 164aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org SkIPoint srcOffset = SkIPoint::Make(0, 0); 1656aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org if (this->getInput(0) && 1664cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org !this->getInput(0)->getInputResultGPU(proxy, src, ctx, &input, &srcOffset)) { 167d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org return false; 168d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org } 169b8d00db075b5ea09e353508a26ef5ced50722a6ccommit-bot@chromium.org GrTexture* srcTexture = input.getTexture(); 1704e16bb2a322f2bd16cb1afd2f78c27e420a4b9dbsenorblanco@chromium.org SkIRect bounds; 171118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org if (!this->applyCropRect(ctx, proxy, input, &srcOffset, &bounds, &input)) { 1724e16bb2a322f2bd16cb1afd2f78c27e420a4b9dbsenorblanco@chromium.org return false; 1734e16bb2a322f2bd16cb1afd2f78c27e420a4b9dbsenorblanco@chromium.org } 1744e16bb2a322f2bd16cb1afd2f78c27e420a4b9dbsenorblanco@chromium.org SkRect srcRect = SkRect::Make(bounds); 1754e16bb2a322f2bd16cb1afd2f78c27e420a4b9dbsenorblanco@chromium.org SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height()); 176d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org GrContext* context = srcTexture->getContext(); 177d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org 178d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org GrTextureDesc desc; 179d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org desc.fFlags = kRenderTarget_GrTextureFlagBit, 1804e16bb2a322f2bd16cb1afd2f78c27e420a4b9dbsenorblanco@chromium.org desc.fWidth = bounds.width(); 1814e16bb2a322f2bd16cb1afd2f78c27e420a4b9dbsenorblanco@chromium.org desc.fHeight = bounds.height(); 182d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org desc.fConfig = kRGBA_8888_GrPixelConfig; 183d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org 184d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org GrAutoScratchTexture dst(context, desc); 185d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org GrContext::AutoMatrix am; 186d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org am.setIdentity(context); 187d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org GrContext::AutoRenderTarget art(context, dst.texture()->asRenderTarget()); 1884e16bb2a322f2bd16cb1afd2f78c27e420a4b9dbsenorblanco@chromium.org GrContext::AutoClip acs(context, dstRect); 189d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org GrEffectRef* effect; 190aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org offset->fX = bounds.left(); 191aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org offset->fY = bounds.top(); 192aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org bounds.offset(-srcOffset); 1934cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org SkMatrix matrix(ctx.ctm()); 194fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org matrix.postTranslate(SkIntToScalar(-bounds.left()), SkIntToScalar(-bounds.top())); 1957938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org this->asNewEffect(&effect, srcTexture, matrix, bounds); 196d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org SkASSERT(effect); 197d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org SkAutoUnref effectRef(effect); 198d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org GrPaint paint; 19942dacab4e7366d9f53989558cc8d045c3d065bcdcommit-bot@chromium.org paint.addColorEffect(effect); 2004e16bb2a322f2bd16cb1afd2f78c27e420a4b9dbsenorblanco@chromium.org context->drawRectToRect(paint, dstRect, srcRect); 2014e16bb2a322f2bd16cb1afd2f78c27e420a4b9dbsenorblanco@chromium.org 202d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org SkAutoTUnref<GrTexture> resultTex(dst.detach()); 2036aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org WrapTexture(resultTex, bounds.width(), bounds.height(), result); 204d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org return true; 205d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org#else 206c2594f41066102d7a8a73effd3c574142a018b9asenorblanco@chromium.org return false; 207d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org#endif 208bf2768bab9f3b21c03a8f9a75dc891231d5857ccsenorblanco@chromium.org} 209bf2768bab9f3b21c03a8f9a75dc891231d5857ccsenorblanco@chromium.org 210118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.orgbool SkImageFilter::applyCropRect(const Context& ctx, const SkBitmap& src, 211118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org const SkIPoint& srcOffset, SkIRect* bounds) const { 212118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org SkIRect srcBounds; 213118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org src.getBounds(&srcBounds); 214118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org srcBounds.offset(srcOffset); 215fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org SkRect cropRect; 216118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org ctx.ctm().mapRect(&cropRect, fCropRect.rect()); 217b295fb6ff3222453912dfcb7a1ea5184d40014b5senorblanco@chromium.org SkIRect cropRectI; 218b295fb6ff3222453912dfcb7a1ea5184d40014b5senorblanco@chromium.org cropRect.roundOut(&cropRectI); 2193f1f2a3a59c43e5bce67ab98e55df45bc7c933a3senorblanco@chromium.org uint32_t flags = fCropRect.flags(); 220118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org if (flags & CropRect::kHasLeft_CropEdge) srcBounds.fLeft = cropRectI.fLeft; 221118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org if (flags & CropRect::kHasTop_CropEdge) srcBounds.fTop = cropRectI.fTop; 222118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org if (flags & CropRect::kHasRight_CropEdge) srcBounds.fRight = cropRectI.fRight; 223118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org if (flags & CropRect::kHasBottom_CropEdge) srcBounds.fBottom = cropRectI.fBottom; 224118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org if (!srcBounds.intersect(ctx.clipBounds())) { 225118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org return false; 226118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org } 227118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org *bounds = srcBounds; 228118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org return true; 229118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org} 230118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org 231118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.orgbool SkImageFilter::applyCropRect(const Context& ctx, Proxy* proxy, const SkBitmap& src, 232118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org SkIPoint* srcOffset, SkIRect* bounds, SkBitmap* dst) const { 233118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org SkIRect srcBounds; 234118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org src.getBounds(&srcBounds); 235118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org srcBounds.offset(*srcOffset); 236118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org SkRect cropRect; 237118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org ctx.ctm().mapRect(&cropRect, fCropRect.rect()); 238118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org SkIRect cropRectI; 239118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org cropRect.roundOut(&cropRectI); 240118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org uint32_t flags = fCropRect.flags(); 241118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org *bounds = srcBounds; 242118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org if (flags & CropRect::kHasLeft_CropEdge) bounds->fLeft = cropRectI.fLeft; 243118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org if (flags & CropRect::kHasTop_CropEdge) bounds->fTop = cropRectI.fTop; 244118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org if (flags & CropRect::kHasRight_CropEdge) bounds->fRight = cropRectI.fRight; 245118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org if (flags & CropRect::kHasBottom_CropEdge) bounds->fBottom = cropRectI.fBottom; 246118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org if (!bounds->intersect(ctx.clipBounds())) { 247118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org return false; 248118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org } 249118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org if (srcBounds.contains(*bounds)) { 250118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org *dst = src; 251118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org return true; 252118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org } else { 253118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(bounds->width(), bounds->height())); 254118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org if (!device) { 255118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org return false; 256118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org } 257118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org SkCanvas canvas(device); 258118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org canvas.clear(0x00000000); 259118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org canvas.drawBitmap(src, srcOffset->x() - bounds->x(), srcOffset->y() - bounds->y()); 260118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org *srcOffset = SkIPoint::Make(bounds->x(), bounds->y()); 261118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org *dst = device->accessBitmap(false); 262118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org return true; 263118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org } 264194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org} 265194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org 266bf2768bab9f3b21c03a8f9a75dc891231d5857ccsenorblanco@chromium.orgbool SkImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm, 267c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org SkIRect* dst) const { 268c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org if (fInputCount < 1) { 269c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org return false; 270c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org } 271c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org 272c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org SkIRect bounds; 273c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org for (int i = 0; i < fInputCount; ++i) { 274c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org SkImageFilter* filter = this->getInput(i); 275c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org SkIRect rect = src; 276c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org if (filter && !filter->filterBounds(src, ctm, &rect)) { 277c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org return false; 278c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org } 279c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org if (0 == i) { 280c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org bounds = rect; 281c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org } else { 282c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org bounds.join(rect); 283c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org } 284c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org } 285c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org 286c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org // don't modify dst until now, so we don't accidentally change it in the 287c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org // loop, but then return false on the next filter. 288c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org *dst = bounds; 289bf2768bab9f3b21c03a8f9a75dc891231d5857ccsenorblanco@chromium.org return true; 290bf2768bab9f3b21c03a8f9a75dc891231d5857ccsenorblanco@chromium.org} 291bf2768bab9f3b21c03a8f9a75dc891231d5857ccsenorblanco@chromium.org 2927938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.orgbool SkImageFilter::asNewEffect(GrEffectRef**, GrTexture*, const SkMatrix&, const SkIRect&) const { 293bf2768bab9f3b21c03a8f9a75dc891231d5857ccsenorblanco@chromium.org return false; 294bf2768bab9f3b21c03a8f9a75dc891231d5857ccsenorblanco@chromium.org} 2958d21f6c7a9d0cf4f87d77c235c6da7203620c7e5senorblanco@chromium.org 296a1c511b8704c6c266b90860a4c68f30ca7514f9bsugoi@google.combool SkImageFilter::asColorFilter(SkColorFilter**) const { 297a1c511b8704c6c266b90860a4c68f30ca7514f9bsugoi@google.com return false; 2988d21f6c7a9d0cf4f87d77c235c6da7203620c7e5senorblanco@chromium.org} 2996aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org 3001a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.orgvoid SkImageFilter::SetExternalCache(Cache* cache) { 3011a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org SkRefCnt_SafeAssign(gExternalCache, cache); 3021a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org} 3031a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org 3041a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.orgSkImageFilter::Cache* SkImageFilter::GetExternalCache() { 3051a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org return gExternalCache; 3061a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org} 3071a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org 3086aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org#if SK_SUPPORT_GPU 3096aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org 3106aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.orgvoid SkImageFilter::WrapTexture(GrTexture* texture, int width, int height, SkBitmap* result) { 3116aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org SkImageInfo info = SkImageInfo::MakeN32Premul(width, height); 3126aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org result->setConfig(info); 3136aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org result->setPixelRef(SkNEW_ARGS(SkGrPixelRef, (info, texture)))->unref(); 3146aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org} 3156aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org 3166aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.orgbool SkImageFilter::getInputResultGPU(SkImageFilter::Proxy* proxy, 3174cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org const SkBitmap& src, const Context& ctx, 3186aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org SkBitmap* result, SkIPoint* offset) const { 3196aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org // Ensure that GrContext calls under filterImage and filterImageGPU below will see an identity 3206aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org // matrix with no clip and that the matrix, clip, and render target set before this function was 3216aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org // called are restored before we return to the caller. 3226aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org GrContext* context = src.getTexture()->getContext(); 3236aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org GrContext::AutoWideOpenIdentityDraw awoid(context, NULL); 3246aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org if (this->canFilterImageGPU()) { 3254cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org return this->filterImageGPU(proxy, src, ctx, result, offset); 3266aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org } else { 3274cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org if (this->filterImage(proxy, src, ctx, result, offset)) { 3286aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org if (!result->getTexture()) { 3296aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org SkImageInfo info; 3306aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org if (!result->asImageInfo(&info)) { 3316aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org return false; 3326aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org } 3336aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org GrTexture* resultTex = GrLockAndRefCachedBitmapTexture(context, *result, NULL); 3346aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org result->setPixelRef(new SkGrPixelRef(info, resultTex))->unref(); 3356aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org GrUnlockAndUnrefCachedBitmapTexture(resultTex); 3366aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org } 3376aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org return true; 3386aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org } else { 3396aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org return false; 3406aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org } 3416aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org } 3426aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org} 3436aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org#endif 344f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org 345f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.orgstatic uint32_t compute_hash(const uint32_t* data, int count) { 346f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org uint32_t hash = 0; 347f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org 348f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org for (int i = 0; i < count; ++i) { 349f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org uint32_t k = data[i]; 350f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org k *= 0xcc9e2d51; 351f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org k = (k << 15) | (k >> 17); 352f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org k *= 0x1b873593; 353f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org 354f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org hash ^= k; 355f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org hash = (hash << 13) | (hash >> 19); 356f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org hash *= 5; 357f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org hash += 0xe6546b64; 358f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org } 359f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org 360f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org // hash ^= size; 361f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org hash ^= hash >> 16; 362f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org hash *= 0x85ebca6b; 363f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org hash ^= hash >> 13; 364f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org hash *= 0xc2b2ae35; 365f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org hash ^= hash >> 16; 366f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org 367f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org return hash; 368f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org} 369f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org 370f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.orgclass CacheImpl : public SkImageFilter::Cache { 371f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.orgpublic: 372f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org explicit CacheImpl(int minChildren) : fMinChildren(minChildren) {} 373f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org virtual ~CacheImpl(); 374f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org bool get(const SkImageFilter* key, SkBitmap* result, SkIPoint* offset) SK_OVERRIDE; 375f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org void set(const SkImageFilter* key, const SkBitmap& result, const SkIPoint& offset) SK_OVERRIDE; 3761a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org void remove(const SkImageFilter* key) SK_OVERRIDE; 377f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.orgprivate: 378f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org typedef const SkImageFilter* Key; 379f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org struct Value { 380f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org Value(Key key, const SkBitmap& bitmap, const SkIPoint& offset) 381f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org : fKey(key), fBitmap(bitmap), fOffset(offset) {} 382f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org Key fKey; 383f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org SkBitmap fBitmap; 384f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org SkIPoint fOffset; 385f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org static const Key& GetKey(const Value& v) { 386f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org return v.fKey; 387f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org } 388f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org static uint32_t Hash(Key key) { 389f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org return compute_hash(reinterpret_cast<const uint32_t*>(&key), sizeof(Key) / sizeof(uint32_t)); 390f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org } 391f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org }; 392f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org SkTDynamicHash<Value, Key> fData; 393f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org int fMinChildren; 394f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org}; 395f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org 396f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.orgbool CacheImpl::get(const SkImageFilter* key, SkBitmap* result, SkIPoint* offset) { 397f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org Value* v = fData.find(key); 398f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org if (v) { 399f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org *result = v->fBitmap; 400f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org *offset = v->fOffset; 401f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org return true; 402f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org } 403f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org return false; 404f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org} 405f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org 4061a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.orgvoid CacheImpl::remove(const SkImageFilter* key) { 4071a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org Value* v = fData.find(key); 4081a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org if (v) { 4091a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org fData.remove(key); 4101a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org delete v; 4111a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org } 4121a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org} 4131a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org 414f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.orgvoid CacheImpl::set(const SkImageFilter* key, const SkBitmap& result, const SkIPoint& offset) { 415f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org if (key->getRefCnt() >= fMinChildren) { 416f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org fData.add(new Value(key, result, offset)); 417f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org } 418f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org} 419f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org 420f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.orgSkImageFilter::Cache* SkImageFilter::Cache::Create(int minChildren) { 421f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org return new CacheImpl(minChildren); 422f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org} 423f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org 424f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.orgCacheImpl::~CacheImpl() { 425f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org SkTDynamicHash<Value, Key>::Iter iter(&fData); 426f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org 427f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org while (!iter.done()) { 428f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org Value* v = &*iter; 429f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org ++iter; 430f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org delete v; 431f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org } 432f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org} 433