Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(128)

Side by Side Diff: src/effects/SkXfermodeImageFilter.cpp

Issue 920513003: Make filters use SkImage instead of SkBitmap Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright 2013 The Android Open Source Project 2 * Copyright 2013 The Android Open Source Project
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkXfermodeImageFilter.h" 8 #include "SkXfermodeImageFilter.h"
9 #include "SkCanvas.h" 9 #include "SkCanvas.h"
10 #include "SkDevice.h" 10 #include "SkSurface.h"
11 #include "SkColorPriv.h" 11 #include "SkColorPriv.h"
12 #include "SkReadBuffer.h" 12 #include "SkReadBuffer.h"
13 #include "SkWriteBuffer.h" 13 #include "SkWriteBuffer.h"
14 #include "SkXfermode.h" 14 #include "SkXfermode.h"
15 #if SK_SUPPORT_GPU 15 #if SK_SUPPORT_GPU
16 #include "GrContext.h" 16 #include "GrContext.h"
17 #include "effects/GrSimpleTextureEffect.h" 17 #include "effects/GrSimpleTextureEffect.h"
18 #include "SkGr.h" 18 #include "SkGr.h"
19 #endif 19 #endif
20 20
(...skipping 16 matching lines...) Expand all
37 SkAutoTUnref<SkXfermode> mode(buffer.readXfermode()); 37 SkAutoTUnref<SkXfermode> mode(buffer.readXfermode());
38 return Create(mode, common.getInput(0), common.getInput(1), &common.cropRect (), common.uniqueID()); 38 return Create(mode, common.getInput(0), common.getInput(1), &common.cropRect (), common.uniqueID());
39 } 39 }
40 40
41 void SkXfermodeImageFilter::flatten(SkWriteBuffer& buffer) const { 41 void SkXfermodeImageFilter::flatten(SkWriteBuffer& buffer) const {
42 this->INHERITED::flatten(buffer); 42 this->INHERITED::flatten(buffer);
43 buffer.writeFlattenable(fMode); 43 buffer.writeFlattenable(fMode);
44 } 44 }
45 45
46 bool SkXfermodeImageFilter::onFilterImage(Proxy* proxy, 46 bool SkXfermodeImageFilter::onFilterImage(Proxy* proxy,
47 const SkBitmap& src, 47 SkImage& src,
48 const Context& ctx, 48 const Context& ctx,
49 SkBitmap* dst, 49 SkAutoTUnref<SkImage>& dst,
50 SkIPoint* offset) const { 50 SkIPoint* offset) const {
51 SkBitmap background = src, foreground = src; 51 SkAutoTUnref<SkImage> background(SkRef(&src));
52 SkAutoTUnref<SkImage> foreground(SkRef(&src));
52 SkImageFilter* backgroundInput = getInput(0); 53 SkImageFilter* backgroundInput = getInput(0);
53 SkImageFilter* foregroundInput = getInput(1); 54 SkImageFilter* foregroundInput = getInput(1);
54 SkIPoint backgroundOffset = SkIPoint::Make(0, 0); 55 SkIPoint backgroundOffset = SkIPoint::Make(0, 0);
56 //TODO MAKE APPLY CROP RECT PTR TO HANDLE NULL.
55 if (backgroundInput && 57 if (backgroundInput &&
56 !backgroundInput->filterImage(proxy, src, ctx, &background, &backgroundO ffset)) { 58 !backgroundInput->filterImage(proxy, src, ctx, background, &backgroundOf fset)) {
57 background.reset(); 59 background.reset(NULL);
58 } 60 }
59 SkIPoint foregroundOffset = SkIPoint::Make(0, 0); 61 SkIPoint foregroundOffset = SkIPoint::Make(0, 0);
60 if (foregroundInput && 62 if (foregroundInput &&
61 !foregroundInput->filterImage(proxy, src, ctx, &foreground, &foregroundO ffset)) { 63 !foregroundInput->filterImage(proxy, src, ctx, foreground, &foregroundOf fset)) {
62 foreground.reset(); 64 foreground.reset(NULL);
63 } 65 }
64 66
65 SkIRect bounds, foregroundBounds; 67 SkIRect bounds, foregroundBounds;
66 if (!applyCropRect(ctx, foreground, foregroundOffset, &foregroundBounds)) { 68 if (!applyCropRect(ctx, *foreground, foregroundOffset, &foregroundBounds)) {
67 foregroundBounds.setEmpty(); 69 foregroundBounds.setEmpty();
68 foreground.reset(); 70 foreground.reset(NULL);
69 } 71 }
70 if (!applyCropRect(ctx, background, backgroundOffset, &bounds)) { 72 if (!applyCropRect(ctx, *background, backgroundOffset, &bounds)) {
71 bounds.setEmpty(); 73 bounds.setEmpty();
72 background.reset(); 74 background.reset(NULL);
73 } 75 }
74 bounds.join(foregroundBounds); 76 bounds.join(foregroundBounds);
75 if (bounds.isEmpty()) { 77 if (bounds.isEmpty()) {
76 return false; 78 return false;
77 } 79 }
78 80
79 SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(bounds.width(), bounds .height())); 81 SkAutoTUnref<SkSurface> surface(proxy->createSurface(bounds.width(), bounds. height()));
80 if (NULL == device.get()) { 82 if (NULL == surface) {
81 return false; 83 return false;
82 } 84 }
83 SkCanvas canvas(device); 85 SkCanvas* canvas = surface->getCanvas();
84 canvas.translate(SkIntToScalar(-bounds.left()), SkIntToScalar(-bounds.top()) ); 86 canvas->translate(SkIntToScalar(-bounds.left()), SkIntToScalar(-bounds.top() ));
85 SkPaint paint; 87 SkPaint paint;
86 paint.setXfermodeMode(SkXfermode::kSrc_Mode); 88 paint.setXfermodeMode(SkXfermode::kSrc_Mode);
87 canvas.drawBitmap(background, SkIntToScalar(backgroundOffset.fX), 89 canvas->drawImage(background, SkIntToScalar(backgroundOffset.fX),
88 SkIntToScalar(backgroundOffset.fY), &paint); 90 SkIntToScalar(backgroundOffset.fY), &paint);
89 paint.setXfermode(fMode); 91 paint.setXfermode(fMode);
90 canvas.drawBitmap(foreground, SkIntToScalar(foregroundOffset.fX), 92 canvas->drawImage(foreground, SkIntToScalar(foregroundOffset.fX),
91 SkIntToScalar(foregroundOffset.fY), &paint); 93 SkIntToScalar(foregroundOffset.fY), &paint);
92 canvas.clipRect(SkRect::Make(foregroundBounds), SkRegion::kDifference_Op); 94 canvas->clipRect(SkRect::Make(foregroundBounds), SkRegion::kDifference_Op);
93 paint.setColor(SK_ColorTRANSPARENT); 95 paint.setColor(SK_ColorTRANSPARENT);
94 canvas.drawPaint(paint); 96 canvas->drawPaint(paint);
95 *dst = device->accessBitmap(false); 97
98 foreground.reset(NULL);
99 background.reset(NULL);
100
101 SkImage* image = surface->newImageSnapshot(SkSurface::kYes_Budgeted);
102 if (NULL == image) {
103 return false;
104 }
105 dst.reset(image);
106
96 offset->fX = bounds.left(); 107 offset->fX = bounds.left();
97 offset->fY = bounds.top(); 108 offset->fY = bounds.top();
98 return true; 109 return true;
99 } 110 }
100 111
101 #ifndef SK_IGNORE_TO_STRING 112 #ifndef SK_IGNORE_TO_STRING
102 void SkXfermodeImageFilter::toString(SkString* str) const { 113 void SkXfermodeImageFilter::toString(SkString* str) const {
103 str->appendf("SkXfermodeImageFilter: ("); 114 str->appendf("SkXfermodeImageFilter: (");
104 str->appendf("xfermode: ("); 115 str->appendf("xfermode: (");
105 if (fMode) { 116 if (fMode) {
106 fMode->toString(str); 117 fMode->toString(str);
107 } 118 }
108 str->append("))"); 119 str->append("))");
109 } 120 }
110 #endif 121 #endif
111 122
112 #if SK_SUPPORT_GPU 123 #if SK_SUPPORT_GPU
113 124
114 bool SkXfermodeImageFilter::canFilterImageGPU() const { 125 bool SkXfermodeImageFilter::canFilterImageGPU() const {
115 return fMode && fMode->asFragmentProcessor(NULL, NULL) && !cropRectIsSet(); 126 return fMode && fMode->asFragmentProcessor(NULL, NULL) && !cropRectIsSet();
116 } 127 }
117 128
118 bool SkXfermodeImageFilter::filterImageGPU(Proxy* proxy, 129 bool SkXfermodeImageFilter::filterImageGPU(Proxy* proxy,
119 const SkBitmap& src, 130 SkImage& src,
120 const Context& ctx, 131 const Context& ctx,
121 SkBitmap* result, 132 SkAutoTUnref<SkImage>& result,
122 SkIPoint* offset) const { 133 SkIPoint* offset) const {
123 SkBitmap background = src; 134 SkAutoTUnref<SkImage> background(SkRef(&src));
124 SkIPoint backgroundOffset = SkIPoint::Make(0, 0); 135 SkIPoint backgroundOffset = SkIPoint::Make(0, 0);
125 if (getInput(0) && !getInput(0)->getInputResultGPU(proxy, src, ctx, &backgro und, 136 if (getInput(0) && !getInput(0)->getInputResultGPU(proxy, src, ctx, backgrou nd,
126 &backgroundOffset)) { 137 &backgroundOffset)) {
127 return onFilterImage(proxy, src, ctx, result, offset); 138 return onFilterImage(proxy, src, ctx, result, offset);
128 } 139 }
129 GrTexture* backgroundTex = background.getTexture(); 140 GrTexture* backgroundTex = background->getTexture();
130 141
131 if (NULL == backgroundTex) { 142 if (NULL == backgroundTex) {
132 SkASSERT(false); 143 SkASSERT(false);
133 return false; 144 return false;
134 } 145 }
135 146
136 SkBitmap foreground = src; 147 SkAutoTUnref<SkImage> foreground(SkRef(&src));
137 SkIPoint foregroundOffset = SkIPoint::Make(0, 0); 148 SkIPoint foregroundOffset = SkIPoint::Make(0, 0);
138 if (getInput(1) && !getInput(1)->getInputResultGPU(proxy, src, ctx, &foregro und, 149 if (getInput(1) && !getInput(1)->getInputResultGPU(proxy, src, ctx, foregrou nd,
139 &foregroundOffset)) { 150 &foregroundOffset)) {
140 return onFilterImage(proxy, src, ctx, result, offset); 151 return onFilterImage(proxy, src, ctx, result, offset);
141 } 152 }
142 GrTexture* foregroundTex = foreground.getTexture(); 153 GrTexture* foregroundTex = foreground->getTexture();
143 GrContext* context = foregroundTex->getContext(); 154 GrContext* context = foregroundTex->getContext();
144 155
145 GrFragmentProcessor* xferProcessor = NULL; 156 GrFragmentProcessor* xferProcessor = NULL;
146 157
147 GrSurfaceDesc desc; 158 GrSurfaceDesc desc;
148 desc.fFlags = kRenderTarget_GrSurfaceFlag | kNoStencil_GrSurfaceFlag; 159 desc.fFlags = kRenderTarget_GrSurfaceFlag | kNoStencil_GrSurfaceFlag;
149 desc.fWidth = src.width(); 160 desc.fWidth = src.width();
150 desc.fHeight = src.height(); 161 desc.fHeight = src.height();
151 desc.fConfig = kSkia8888_GrPixelConfig; 162 desc.fConfig = kSkia8888_GrPixelConfig;
152 SkAutoTUnref<GrTexture> dst( 163 SkAutoTUnref<GrTexture> dst(
153 context->refScratchTexture(desc, GrContext::kApprox_ScratchTexMatch)); 164 context->refScratchTexture(desc, GrContext::kApprox_ScratchTexMatch));
154 if (!dst) { 165 if (!dst) {
155 return false; 166 return false;
156 } 167 }
157 GrContext::AutoRenderTarget art(context, dst->asRenderTarget()); 168 GrContext::AutoRenderTarget art(context, dst->asRenderTarget());
158 169
159 if (!fMode || !fMode->asFragmentProcessor(&xferProcessor, backgroundTex)) { 170 if (!fMode || !fMode->asFragmentProcessor(&xferProcessor, backgroundTex)) {
160 // canFilterImageGPU() should've taken care of this 171 // canFilterImageGPU() should've taken care of this
161 SkASSERT(false); 172 SkASSERT(false);
162 return false; 173 return false;
163 } 174 }
164 175
165 SkMatrix foregroundMatrix = GrCoordTransform::MakeDivByTextureWHMatrix(foreg roundTex); 176 SkMatrix foregroundMatrix = GrCoordTransform::MakeDivByTextureWHMatrix(foreg roundTex);
166 foregroundMatrix.preTranslate(SkIntToScalar(backgroundOffset.fX-foregroundOf fset.fX), 177 foregroundMatrix.preTranslate(SkIntToScalar(backgroundOffset.fX-foregroundOf fset.fX),
167 SkIntToScalar(backgroundOffset.fY-foregroundOf fset.fY)); 178 SkIntToScalar(backgroundOffset.fY-foregroundOf fset.fY));
168 179
169 180
170 SkRect srcRect; 181 SkRect srcRect = SkRect::MakeWH(src.width(), src.height());
171 src.getBounds(&srcRect);
172 182
173 GrPaint paint; 183 GrPaint paint;
174 paint.addColorTextureProcessor(foregroundTex, foregroundMatrix); 184 paint.addColorTextureProcessor(foregroundTex, foregroundMatrix);
175 paint.addColorProcessor(xferProcessor)->unref(); 185 paint.addColorProcessor(xferProcessor)->unref();
176 context->drawRect(paint, SkMatrix::I(), srcRect); 186 context->drawRect(paint, SkMatrix::I(), srcRect);
177 187
178 offset->fX = backgroundOffset.fX; 188 offset->fX = backgroundOffset.fX;
179 offset->fY = backgroundOffset.fY; 189 offset->fY = backgroundOffset.fY;
180 WrapTexture(dst, src.width(), src.height(), result); 190 if (!WrapTexture(dst, src.width(), src.height(), result)) {
191 return false;
192 }
181 return true; 193 return true;
182 } 194 }
183 195
184 #endif 196 #endif
185 197
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698