SkImageFilter.cpp revision 42dacab4e7366d9f53989558cc8d045c3d065bcd
1/* 2 * Copyright 2012 The Android Open Source Project 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8#include "SkImageFilter.h" 9 10#include "SkBitmap.h" 11#include "SkFlattenableBuffers.h" 12#include "SkRect.h" 13#if SK_SUPPORT_GPU 14#include "GrContext.h" 15#include "GrTexture.h" 16#include "SkImageFilterUtils.h" 17#endif 18 19SK_DEFINE_INST_COUNT(SkImageFilter) 20 21SkImageFilter::SkImageFilter(int inputCount, SkImageFilter** inputs) 22 : fInputCount(inputCount), fInputs(new SkImageFilter*[inputCount]) { 23 for (int i = 0; i < inputCount; ++i) { 24 fInputs[i] = inputs[i]; 25 SkSafeRef(fInputs[i]); 26 } 27} 28 29SkImageFilter::SkImageFilter(SkImageFilter* input) 30 : fInputCount(1), fInputs(new SkImageFilter*[1]) { 31 fInputs[0] = input; 32 SkSafeRef(fInputs[0]); 33} 34 35SkImageFilter::SkImageFilter(SkImageFilter* input1, SkImageFilter* input2) 36 : fInputCount(2), fInputs(new SkImageFilter*[2]) { 37 fInputs[0] = input1; 38 fInputs[1] = input2; 39 SkSafeRef(fInputs[0]); 40 SkSafeRef(fInputs[1]); 41} 42 43SkImageFilter::~SkImageFilter() { 44 for (int i = 0; i < fInputCount; i++) { 45 SkSafeUnref(fInputs[i]); 46 } 47 delete[] fInputs; 48} 49 50SkImageFilter::SkImageFilter(SkFlattenableReadBuffer& buffer) 51 : fInputCount(buffer.readInt()), fInputs(new SkImageFilter*[fInputCount]) { 52 for (int i = 0; i < fInputCount; i++) { 53 if (buffer.readBool()) { 54 fInputs[i] = static_cast<SkImageFilter*>(buffer.readFlattenable()); 55 } else { 56 fInputs[i] = NULL; 57 } 58 } 59} 60 61void SkImageFilter::flatten(SkFlattenableWriteBuffer& buffer) const { 62 buffer.writeInt(fInputCount); 63 for (int i = 0; i < fInputCount; i++) { 64 SkImageFilter* input = getInput(i); 65 buffer.writeBool(input != NULL); 66 if (input != NULL) { 67 buffer.writeFlattenable(input); 68 } 69 } 70} 71 72bool SkImageFilter::filterImage(Proxy* proxy, const SkBitmap& src, 73 const SkMatrix& ctm, 74 SkBitmap* result, SkIPoint* loc) { 75 SkASSERT(result); 76 SkASSERT(loc); 77 /* 78 * Give the proxy first shot at the filter. If it returns false, ask 79 * the filter to do it. 80 */ 81 return (proxy && proxy->filterImage(this, src, ctm, result, loc)) || 82 this->onFilterImage(proxy, src, ctm, result, loc); 83} 84 85bool SkImageFilter::filterBounds(const SkIRect& src, const SkMatrix& ctm, 86 SkIRect* dst) { 87 SkASSERT(&src); 88 SkASSERT(dst); 89 return this->onFilterBounds(src, ctm, dst); 90} 91 92bool SkImageFilter::onFilterImage(Proxy*, const SkBitmap&, const SkMatrix&, 93 SkBitmap*, SkIPoint*) { 94 return false; 95} 96 97bool SkImageFilter::canFilterImageGPU() const { 98 return this->asNewEffect(NULL, NULL); 99} 100 101bool SkImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, SkBitmap* result, 102 SkIPoint* offset) { 103#if SK_SUPPORT_GPU 104 SkBitmap input; 105 SkASSERT(fInputCount == 1); 106 if (!SkImageFilterUtils::GetInputResultGPU(this->getInput(0), proxy, src, &input, offset)) { 107 return false; 108 } 109 GrTexture* srcTexture = input.getTexture(); 110 SkRect rect; 111 src.getBounds(&rect); 112 GrContext* context = srcTexture->getContext(); 113 114 GrTextureDesc desc; 115 desc.fFlags = kRenderTarget_GrTextureFlagBit, 116 desc.fWidth = input.width(); 117 desc.fHeight = input.height(); 118 desc.fConfig = kRGBA_8888_GrPixelConfig; 119 120 GrAutoScratchTexture dst(context, desc); 121 GrContext::AutoMatrix am; 122 am.setIdentity(context); 123 GrContext::AutoRenderTarget art(context, dst.texture()->asRenderTarget()); 124 GrContext::AutoClip acs(context, rect); 125 GrEffectRef* effect; 126 this->asNewEffect(&effect, srcTexture); 127 SkASSERT(effect); 128 SkAutoUnref effectRef(effect); 129 GrPaint paint; 130 paint.addColorEffect(effect); 131 context->drawRect(paint, rect); 132 SkAutoTUnref<GrTexture> resultTex(dst.detach()); 133 SkImageFilterUtils::WrapTexture(resultTex, input.width(), input.height(), result); 134 return true; 135#else 136 return false; 137#endif 138} 139 140bool SkImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm, 141 SkIRect* dst) { 142 *dst = src; 143 return true; 144} 145 146bool SkImageFilter::asNewEffect(GrEffectRef**, GrTexture*) const { 147 return false; 148} 149 150bool SkImageFilter::asColorFilter(SkColorFilter**) const { 151 return false; 152} 153