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

Side by Side Diff: src/gpu/SkGr.cpp

Issue 1249543003: Creating functions for uploading a mipmapped texture. (Closed) Base URL: https://chromium.googlesource.com/skia.git@master
Patch Set: Fixing merge mistakes Created 5 years, 2 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 2010 Google Inc. 2 * Copyright 2010 Google Inc.
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 "GrTextureMaker.h"
9
8 #include "SkGr.h" 10 #include "SkGr.h"
9 11
10 #include "GrCaps.h" 12 #include "GrCaps.h"
13 #include "GrContext.h"
11 #include "GrDrawContext.h" 14 #include "GrDrawContext.h"
12 #include "GrXferProcessor.h" 15 #include "GrXferProcessor.h"
13 #include "GrYUVProvider.h" 16 #include "GrYUVProvider.h"
14 17
15 #include "SkColorFilter.h" 18 #include "SkColorFilter.h"
16 #include "SkConfig8888.h" 19 #include "SkConfig8888.h"
17 #include "SkCanvas.h" 20 #include "SkCanvas.h"
18 #include "SkData.h" 21 #include "SkData.h"
19 #include "SkErrorInternals.h" 22 #include "SkErrorInternals.h"
20 #include "SkGrPixelRef.h" 23 #include "SkGrPixelRef.h"
21 #include "SkMessageBus.h" 24 #include "SkMessageBus.h"
25 #include "SkMath.h"
26 #include "SkMipMap.h"
27 #include "SkMipMapLevel.h"
22 #include "SkPixelRef.h" 28 #include "SkPixelRef.h"
23 #include "SkResourceCache.h" 29 #include "SkResourceCache.h"
24 #include "SkTextureCompressor.h" 30 #include "SkTextureCompressor.h"
31 #include "SkTypes.h"
25 #include "SkYUVPlanesCache.h" 32 #include "SkYUVPlanesCache.h"
26 #include "effects/GrBicubicEffect.h" 33 #include "effects/GrBicubicEffect.h"
34 #include "effects/GrConstColorProcessor.h"
27 #include "effects/GrDitherEffect.h" 35 #include "effects/GrDitherEffect.h"
28 #include "effects/GrPorterDuffXferProcessor.h" 36 #include "effects/GrPorterDuffXferProcessor.h"
37 #include "effects/GrXfermodeFragmentProcessor.h"
29 #include "effects/GrYUVtoRGBEffect.h" 38 #include "effects/GrYUVtoRGBEffect.h"
30 39
31 #ifndef SK_IGNORE_ETC1_SUPPORT 40 #ifndef SK_IGNORE_ETC1_SUPPORT
32 # include "ktx.h" 41 # include "ktx.h"
33 # include "etc1.h" 42 # include "etc1.h"
34 #endif 43 #endif
35 44
36 /* Fill out buffer with the compressed format Ganesh expects from a colortable 45 /* Fill out buffer with the compressed format Ganesh expects from a colortable
37 based bitmap. [palette (colortable) + indices]. 46 based bitmap. [palette (colortable) + indices].
38 47
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 for (int y = 0; y < bitmap.height(); y++) { 94 for (int y = 0; y < bitmap.height(); y++) {
86 memcpy(dst, src, width); 95 memcpy(dst, src, width);
87 src += rowBytes; 96 src += rowBytes;
88 dst += width; 97 dst += width;
89 } 98 }
90 } 99 }
91 } 100 }
92 101
93 //////////////////////////////////////////////////////////////////////////////// 102 ////////////////////////////////////////////////////////////////////////////////
94 103
95 struct Stretch { 104 static void get_stretch(const GrCaps& caps, int width, int height,
96 enum Type { 105 const GrTextureParams& params, SkGrStretch* stretch) {
97 kNone_Type, 106 stretch->fType = SkGrStretch::kNone_Type;
98 kBilerp_Type,
99 kNearest_Type
100 } fType;
101 int fWidth;
102 int fHeight;
103 };
104
105 static void get_stretch(const GrContext* ctx, int width, int height,
106 const GrTextureParams* params, Stretch* stretch) {
107 stretch->fType = Stretch::kNone_Type;
108 bool doStretch = false; 107 bool doStretch = false;
109 if (params && params->isTiled() && !ctx->caps()->npotTextureTileSupport() && 108 if (params.isTiled() && !caps.npotTextureTileSupport() &&
110 (!SkIsPow2(width) || !SkIsPow2(height))) { 109 (!SkIsPow2(width) || !SkIsPow2(height))) {
111 doStretch = true; 110 doStretch = true;
112 stretch->fWidth = GrNextPow2(SkTMax(width, ctx->caps()->minTextureSize( ))); 111 stretch->fWidth = GrNextPow2(SkTMax(width, caps.minTextureSize()));
113 stretch->fHeight = GrNextPow2(SkTMax(height, ctx->caps()->minTextureSize ())); 112 stretch->fHeight = GrNextPow2(SkTMax(height, caps.minTextureSize()));
114 } else if (width < ctx->caps()->minTextureSize() || height < ctx->caps()->mi nTextureSize()) { 113 } else if (width < caps.minTextureSize() || height < caps.minTextureSize()) {
115 // The small texture issues appear to be with tiling. Hence it seems ok to scale them 114 // The small texture issues appear to be with tiling. Hence it seems ok to scale them
116 // up using the GPU. If issues persist we may need to CPU-stretch. 115 // up using the GPU. If issues persist we may need to CPU-stretch.
117 doStretch = true; 116 doStretch = true;
118 stretch->fWidth = SkTMax(width, ctx->caps()->minTextureSize()); 117 stretch->fWidth = SkTMax(width, caps.minTextureSize());
119 stretch->fHeight = SkTMax(height, ctx->caps()->minTextureSize()); 118 stretch->fHeight = SkTMax(height, caps.minTextureSize());
120 } 119 }
121 if (doStretch) { 120 if (doStretch) {
122 if (params) { 121 switch(params.filterMode()) {
123 switch(params->filterMode()) { 122 case GrTextureParams::kNone_FilterMode:
124 case GrTextureParams::kNone_FilterMode: 123 stretch->fType = SkGrStretch::kNearest_Type;
125 stretch->fType = Stretch::kNearest_Type; 124 break;
126 break; 125 case GrTextureParams::kBilerp_FilterMode:
127 case GrTextureParams::kBilerp_FilterMode: 126 case GrTextureParams::kMipMap_FilterMode:
128 case GrTextureParams::kMipMap_FilterMode: 127 stretch->fType = SkGrStretch::kBilerp_Type;
129 stretch->fType = Stretch::kBilerp_Type; 128 break;
130 break;
131 }
132 } else {
133 stretch->fType = Stretch::kBilerp_Type;
134 } 129 }
135 } else { 130 } else {
136 stretch->fWidth = -1; 131 stretch->fWidth = -1;
137 stretch->fHeight = -1; 132 stretch->fHeight = -1;
138 stretch->fType = Stretch::kNone_Type; 133 stretch->fType = SkGrStretch::kNone_Type;
139 } 134 }
140 } 135 }
141 136
142 static bool make_stretched_key(const GrUniqueKey& origKey, const Stretch& stretc h, 137 bool GrMakeStretchedKey(const GrUniqueKey& origKey, const SkGrStretch& stretch,
143 GrUniqueKey* stretchedKey) { 138 GrUniqueKey* stretchedKey) {
144 if (origKey.isValid() && Stretch::kNone_Type != stretch.fType) { 139 if (origKey.isValid() && SkGrStretch::kNone_Type != stretch.fType) {
145 uint32_t width = SkToU16(stretch.fWidth); 140 uint32_t width = SkToU16(stretch.fWidth);
146 uint32_t height = SkToU16(stretch.fHeight); 141 uint32_t height = SkToU16(stretch.fHeight);
147 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain() ; 142 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain() ;
148 GrUniqueKey::Builder builder(stretchedKey, origKey, kDomain, 2); 143 GrUniqueKey::Builder builder(stretchedKey, origKey, kDomain, 2);
149 builder[0] = stretch.fType; 144 builder[0] = stretch.fType;
150 builder[1] = width | (height << 16); 145 builder[1] = width | (height << 16);
151 builder.finish(); 146 builder.finish();
152 return true; 147 return true;
153 } 148 }
154 SkASSERT(!stretchedKey->isValid()); 149 SkASSERT(!stretchedKey->isValid());
155 return false; 150 return false;
156 } 151 }
157 152
158 static void make_unstretched_key(GrUniqueKey* key, uint32_t imageID, const SkIRe ct& subset) { 153 static void make_unstretched_key(GrUniqueKey* key, uint32_t imageID, const SkIRe ct& subset, bool isMipMapped = false) {
159 SkASSERT(SkIsU16(subset.width())); 154 SkASSERT(SkIsU16(subset.width()));
160 SkASSERT(SkIsU16(subset.height())); 155 SkASSERT(SkIsU16(subset.height()));
161 156
162 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); 157 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
163 GrUniqueKey::Builder builder(key, kDomain, 4); 158 GrUniqueKey::Builder builder(key, kDomain, 5);
164 builder[0] = imageID; 159 builder[0] = imageID;
165 builder[1] = subset.x(); 160 builder[1] = subset.x();
166 builder[2] = subset.y(); 161 builder[2] = subset.y();
167 builder[3] = subset.width() | (subset.height() << 16); 162 builder[3] = subset.width() | (subset.height() << 16);
163 builder[4] = isMipMapped;
168 } 164 }
169 165
170 void GrMakeKeyFromImageID(GrUniqueKey* key, uint32_t imageID, const SkIRect& sub set, 166 void GrMakeKeyFromImageID(GrUniqueKey* key, uint32_t imageID, const SkIRect& sub set,
171 const GrCaps& caps, SkImageUsageType usage) { 167 const GrCaps& caps, const GrTextureParams& params) {
172 const Stretch::Type stretches[] = { 168 SkGrStretch stretch;
173 Stretch::kNone_Type, // kUntiled_SkImageUsageType 169 get_stretch(caps, subset.width(), subset.height(), params, &stretch);
174 Stretch::kNearest_Type, // kTiled_Unfiltered_SkImageUsageType 170 if (SkGrStretch::kNone_Type != stretch.fType) {
175 Stretch::kBilerp_Type, // kTiled_Filtered_SkImageUsageType
176 };
177
178 const bool isPow2 = SkIsPow2(subset.width()) && SkIsPow2(subset.height());
179 const bool needToStretch = !isPow2 &&
180 usage != kUntiled_SkImageUsageType &&
181 !caps.npotTextureTileSupport();
182
183 if (needToStretch) {
184 GrUniqueKey tmpKey; 171 GrUniqueKey tmpKey;
185 make_unstretched_key(&tmpKey, imageID, subset); 172 make_unstretched_key(&tmpKey, imageID, subset);
186 173 if (!GrMakeStretchedKey(tmpKey, stretch, key)) {
187 Stretch stretch; 174 *key = tmpKey;
188 stretch.fType = stretches[usage];
189 stretch.fWidth = SkNextPow2(subset.width());
190 stretch.fHeight = SkNextPow2(subset.height());
191 if (!make_stretched_key(tmpKey, stretch, key)) {
192 goto UNSTRETCHED;
193 } 175 }
194 } else { 176 } else {
195 UNSTRETCHED:
196 make_unstretched_key(key, imageID, subset); 177 make_unstretched_key(key, imageID, subset);
197 } 178 }
198 } 179 }
199 180
200 static void make_image_keys(uint32_t imageID, const SkIRect& subset, const Stret ch& stretch, 181 static void make_image_keys(uint32_t imageID, const SkIRect& subset, const SkGrS tretch& stretch,
201 GrUniqueKey* key, GrUniqueKey* stretchedKey) { 182 GrUniqueKey* key, GrUniqueKey* stretchedKey) {
202 make_unstretched_key(key, imageID, subset); 183 make_unstretched_key(key, imageID, subset);
203 if (Stretch::kNone_Type != stretch.fType) { 184 if (SkGrStretch::kNone_Type != stretch.fType) {
204 make_stretched_key(*key, stretch, stretchedKey); 185 GrMakeStretchedKey(*key, stretch, stretchedKey);
205 } 186 }
206 } 187 }
207 188
208 GrSurfaceDesc GrImageInfoToSurfaceDesc(const SkImageInfo& info) { 189 GrSurfaceDesc GrImageInfoToSurfaceDesc(const SkImageInfo& info) {
209 GrSurfaceDesc desc; 190 GrSurfaceDesc desc;
210 desc.fFlags = kNone_GrSurfaceFlags; 191 desc.fFlags = kNone_GrSurfaceFlags;
211 desc.fWidth = info.width(); 192 desc.fWidth = info.width();
212 desc.fHeight = info.height(); 193 desc.fHeight = info.height();
213 desc.fConfig = SkImageInfo2GrPixelConfig(info); 194 desc.fConfig = SkImageInfo2GrPixelConfig(info);
214 desc.fSampleCnt = 0; 195 desc.fSampleCnt = 0;
215 return desc; 196 return desc;
216 } 197 }
217 198
218 namespace { 199 namespace {
219 200
220 // When the SkPixelRef genID changes, invalidate a corresponding GrResource desc ribed by key. 201 // When the SkPixelRef genID changes, invalidate a corresponding GrResource desc ribed by key.
221 class BitmapInvalidator : public SkPixelRef::GenIDChangeListener { 202 class BitmapInvalidator : public SkPixelRef::GenIDChangeListener {
222 public: 203 public:
223 explicit BitmapInvalidator(const GrUniqueKey& key) : fMsg(key) {} 204 explicit BitmapInvalidator(const GrUniqueKey& key) : fMsg(key) {}
224 private: 205 private:
225 GrUniqueKeyInvalidatedMessage fMsg; 206 GrUniqueKeyInvalidatedMessage fMsg;
226 207
227 void onChange() override { 208 void onChange() override {
228 SkMessageBus<GrUniqueKeyInvalidatedMessage>::Post(fMsg); 209 SkMessageBus<GrUniqueKeyInvalidatedMessage>::Post(fMsg);
229 } 210 }
230 }; 211 };
231 212
232 } // namespace 213 } // namespace
233 214
215 static void add_key_and_invalidation_listener(GrContext* ctx,
216 const GrUniqueKey& optionalKey,
217 SkPixelRef* pixelRefForInvalidatio nNotification,
218 GrTexture& result) {
219 if (optionalKey.isValid()) {
220 if (pixelRefForInvalidationNotification) {
221 BitmapInvalidator* listener = new BitmapInvalidator(optionalKey);
222 pixelRefForInvalidationNotification->addGenIDChangeListener(listener );
223 }
224 ctx->textureProvider()->assignUniqueKeyToTexture(optionalKey, &result);
225 }
226 }
234 227
235 GrTexture* GrCreateTextureForPixels(GrContext* ctx, 228 GrTexture* GrCreateTextureForPixels(GrContext* ctx,
236 const GrUniqueKey& optionalKey, 229 const GrUniqueKey& optionalKey,
237 GrSurfaceDesc desc, 230 GrSurfaceDesc desc,
238 SkPixelRef* pixelRefForInvalidationNotificat ion, 231 SkPixelRef* pixelRefForInvalidationNotificat ion,
239 const void* pixels, 232 const void* pixels,
240 size_t rowBytes) { 233 size_t rowBytes) {
241 GrTexture* result = ctx->textureProvider()->createTexture(desc, true, pixels , rowBytes); 234 GrTexture* result = ctx->textureProvider()->createTexture(desc, true, pixels , rowBytes);
242 if (result && optionalKey.isValid()) { 235 if (result) {
243 if (pixelRefForInvalidationNotification) { 236 add_key_and_invalidation_listener(ctx, optionalKey, pixelRefForInvalidat ionNotification,
244 BitmapInvalidator* listener = new BitmapInvalidator(optionalKey); 237 *result);
245 pixelRefForInvalidationNotification->addGenIDChangeListener(listener );
246 }
247 ctx->textureProvider()->assignUniqueKeyToTexture(optionalKey, result);
248 } 238 }
249 return result; 239 return result;
250 } 240 }
251 241
242 GrTexture* GrCreateTextureForPixels(GrContext* ctx,
243 const GrUniqueKey& optionalKey,
244 GrSurfaceDesc desc,
245 SkPixelRef* pixelRefForInvalidationNotificat ion,
246 const SkTArray<SkMipMapLevel>& texels) {
247 GrTexture* result = ctx->textureProvider()->createTexture(desc, true, texels );
248 if (result) {
249 add_key_and_invalidation_listener(ctx, optionalKey, pixelRefForInvalidat ionNotification,
250 *result);
251 }
252 return result;
253 }
254
252 // creates a new texture that is the input texture scaled up. If optionalKey is valid it will be 255 // creates a new texture that is the input texture scaled up. If optionalKey is valid it will be
253 // set on the new texture. stretch controls whether the scaling is done using ne arest or bilerp 256 // set on the new texture. stretch controls whether the scaling is done using ne arest or bilerp
254 // filtering and the size to stretch the texture to. 257 // filtering and the size to stretch the texture to.
255 GrTexture* stretch_texture(GrTexture* inputTexture, const Stretch& stretch, 258 GrTexture* stretch_texture(GrTexture* inputTexture, const SkGrStretch& stretch,
256 SkPixelRef* pixelRef, 259 SkPixelRef* pixelRef,
257 const GrUniqueKey& optionalKey) { 260 const GrUniqueKey& optionalKey) {
258 SkASSERT(Stretch::kNone_Type != stretch.fType); 261 SkASSERT(SkGrStretch::kNone_Type != stretch.fType);
259 262
260 GrContext* context = inputTexture->getContext(); 263 GrContext* context = inputTexture->getContext();
261 SkASSERT(context); 264 SkASSERT(context);
262 const GrCaps* caps = context->caps(); 265 const GrCaps* caps = context->caps();
263 266
264 // Either it's a cache miss or the original wasn't cached to begin with. 267 // Either it's a cache miss or the original wasn't cached to begin with.
265 GrSurfaceDesc rtDesc = inputTexture->desc(); 268 GrSurfaceDesc rtDesc = inputTexture->desc();
266 rtDesc.fFlags = rtDesc.fFlags | kRenderTarget_GrSurfaceFlag; 269 rtDesc.fFlags = rtDesc.fFlags | kRenderTarget_GrSurfaceFlag;
267 rtDesc.fWidth = stretch.fWidth; 270 rtDesc.fWidth = stretch.fWidth;
268 rtDesc.fHeight = stretch.fHeight; 271 rtDesc.fHeight = stretch.fHeight;
(...skipping 25 matching lines...) Expand all
294 SkAutoTUnref<GrTexture> stretched(GrCreateTextureForPixels(context, optional Key, rtDesc, 297 SkAutoTUnref<GrTexture> stretched(GrCreateTextureForPixels(context, optional Key, rtDesc,
295 pixelRef, nullptr ,0)); 298 pixelRef, nullptr ,0));
296 if (!stretched) { 299 if (!stretched) {
297 return nullptr; 300 return nullptr;
298 } 301 }
299 GrPaint paint; 302 GrPaint paint;
300 303
301 // If filtering is not desired then we want to ensure all texels in the resa mpled image are 304 // If filtering is not desired then we want to ensure all texels in the resa mpled image are
302 // copies of texels from the original. 305 // copies of texels from the original.
303 GrTextureParams params(SkShader::kClamp_TileMode, 306 GrTextureParams params(SkShader::kClamp_TileMode,
304 Stretch::kBilerp_Type == stretch.fType ? 307 SkGrStretch::kBilerp_Type == stretch.fType ?
305 GrTextureParams::kBilerp_FilterMode : 308 GrTextureParams::kBilerp_FilterMode :
306 GrTextureParams::kNone_FilterMode); 309 GrTextureParams::kNone_FilterMode);
307 paint.addColorTextureProcessor(inputTexture, SkMatrix::I(), params); 310 paint.addColorTextureProcessor(inputTexture, SkMatrix::I(), params);
308 311
309 SkRect rect = SkRect::MakeWH(SkIntToScalar(rtDesc.fWidth), SkIntToScalar(rtD esc.fHeight)); 312 SkRect rect = SkRect::MakeWH(SkIntToScalar(rtDesc.fWidth), SkIntToScalar(rtD esc.fHeight));
310 SkRect localRect = SkRect::MakeWH(1.f, 1.f); 313 SkRect localRect = SkRect::MakeWH(1.f, 1.f);
311 314
312 SkAutoTUnref<GrDrawContext> drawContext(context->drawContext()); 315 SkAutoTUnref<GrDrawContext> drawContext(context->drawContext(stretched->asRe nderTarget()));
313 if (!drawContext) { 316 if (!drawContext) {
314 return nullptr; 317 return nullptr;
315 } 318 }
316 319
317 drawContext->drawNonAARectToRect(stretched->asRenderTarget(), GrClip::WideOp en(), paint, 320 drawContext->drawNonAARectToRect(GrClip::WideOpen(), paint, SkMatrix::I(), r ect, localRect);
318 SkMatrix::I(), rect, localRect);
319 321
320 return stretched.detach(); 322 return stretched.detach();
321 } 323 }
322 324
323 GrPixelConfig GrIsCompressedTextureDataSupported(GrContext* ctx, SkData* data, 325 GrPixelConfig GrIsCompressedTextureDataSupported(GrContext* ctx, SkData* data,
324 int expectedW, int expectedH, 326 int expectedW, int expectedH,
325 const void** outStartOfDataToUp load) { 327 const void** outStartOfDataToUp load) {
326 *outStartOfDataToUpload = nullptr; 328 *outStartOfDataToUpload = nullptr;
327 #ifndef SK_IGNORE_ETC1_SUPPORT 329 #ifndef SK_IGNORE_ETC1_SUPPORT
328 if (!ctx->caps()->isConfigTexturable(kETC1_GrPixelConfig)) { 330 if (!ctx->caps()->isConfigTexturable(kETC1_GrPixelConfig)) {
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
414 GrTexture* texture = provider.refAsTexture(ctx, desc, useCache); 416 GrTexture* texture = provider.refAsTexture(ctx, desc, useCache);
415 if (!texture) { 417 if (!texture) {
416 return nullptr; 418 return nullptr;
417 } 419 }
418 420
419 if (useCache) { 421 if (useCache) {
420 BitmapInvalidator* listener = new BitmapInvalidator(optionalKey); 422 BitmapInvalidator* listener = new BitmapInvalidator(optionalKey);
421 pixelRef->addGenIDChangeListener(listener); 423 pixelRef->addGenIDChangeListener(listener);
422 ctx->textureProvider()->assignUniqueKeyToTexture(optionalKey, texture); 424 ctx->textureProvider()->assignUniqueKeyToTexture(optionalKey, texture);
423 } 425 }
424 return texture; 426 return texture;
425 } 427 }
426 428
427 static GrTexture* create_unstretched_bitmap_texture(GrContext* ctx, 429 static GrTexture* create_unstretched_bitmap_texture(GrContext* ctx,
428 const SkBitmap& origBitmap, 430 const SkBitmap& origBitmap,
429 const GrUniqueKey& optionalK ey) { 431 const GrUniqueKey& optionalK ey) {
430 if (origBitmap.width() < ctx->caps()->minTextureSize() || 432 if (origBitmap.width() < ctx->caps()->minTextureSize() ||
431 origBitmap.height() < ctx->caps()->minTextureSize()) { 433 origBitmap.height() < ctx->caps()->minTextureSize()) {
432 return nullptr; 434 return nullptr;
433 } 435 }
434 SkBitmap tmpBitmap; 436 SkBitmap tmpBitmap;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
473 475
474 SkAutoLockPixels alp(*bitmap); 476 SkAutoLockPixels alp(*bitmap);
475 if (!bitmap->readyToDraw()) { 477 if (!bitmap->readyToDraw()) {
476 return nullptr; 478 return nullptr;
477 } 479 }
478 480
479 return GrCreateTextureForPixels(ctx, optionalKey, desc, origBitmap.pixelRef( ), 481 return GrCreateTextureForPixels(ctx, optionalKey, desc, origBitmap.pixelRef( ),
480 bitmap->getPixels(), bitmap->rowBytes()); 482 bitmap->getPixels(), bitmap->rowBytes());
481 } 483 }
482 484
483 static SkBitmap stretch_on_cpu(const SkBitmap& bmp, const Stretch& stretch) { 485 static SkBitmap stretch_on_cpu(const SkBitmap& bmp, const SkGrStretch& stretch) {
484 SkBitmap stretched; 486 SkBitmap stretched;
485 stretched.allocN32Pixels(stretch.fWidth, stretch.fHeight); 487 stretched.allocN32Pixels(stretch.fWidth, stretch.fHeight);
486 SkCanvas canvas(stretched); 488 SkCanvas canvas(stretched);
487 SkPaint paint; 489 SkPaint paint;
488 switch (stretch.fType) { 490 switch (stretch.fType) {
489 case Stretch::kNearest_Type: 491 case SkGrStretch::kNearest_Type:
490 paint.setFilterQuality(kNone_SkFilterQuality); 492 paint.setFilterQuality(kNone_SkFilterQuality);
491 break; 493 break;
492 case Stretch::kBilerp_Type: 494 case SkGrStretch::kBilerp_Type:
493 paint.setFilterQuality(kLow_SkFilterQuality); 495 paint.setFilterQuality(kLow_SkFilterQuality);
494 break; 496 break;
495 case Stretch::kNone_Type: 497 case SkGrStretch::kNone_Type:
496 SkDEBUGFAIL("Shouldn't get here."); 498 SkDEBUGFAIL("Shouldn't get here.");
497 break; 499 break;
498 } 500 }
499 SkRect dstRect = SkRect::MakeWH(SkIntToScalar(stretch.fWidth), SkIntToScalar (stretch.fHeight)); 501 SkRect dstRect = SkRect::MakeWH(SkIntToScalar(stretch.fWidth), SkIntToScalar (stretch.fHeight));
500 canvas.drawBitmapRect(bmp, dstRect, &paint); 502 canvas.drawBitmapRect(bmp, dstRect, &paint);
501 return stretched; 503 return stretched;
502 } 504 }
503 505
504 static GrTexture* create_bitmap_texture(GrContext* ctx,
505 const SkBitmap& bmp,
506 const Stretch& stretch,
507 const GrUniqueKey& unstretchedKey,
508 const GrUniqueKey& stretchedKey) {
509 if (Stretch::kNone_Type != stretch.fType) {
510 SkAutoTUnref<GrTexture> unstretched;
511 // Check if we have the unstretched version in the cache, if not create it.
512 if (unstretchedKey.isValid()) {
513 unstretched.reset(ctx->textureProvider()->findAndRefTextureByUniqueK ey(unstretchedKey));
514 }
515 if (!unstretched) {
516 unstretched.reset(create_unstretched_bitmap_texture(ctx, bmp, unstre tchedKey));
517 if (!unstretched) {
518 // We might not have been able to create a unstrecthed texture b ecause it is smaller
519 // than the min texture size. In that case do cpu stretching.
520 SkBitmap stretchedBmp = stretch_on_cpu(bmp, stretch);
521 return create_unstretched_bitmap_texture(ctx, stretchedBmp, stre tchedKey);
522 }
523 }
524 return stretch_texture(unstretched, stretch, bmp.pixelRef(), stretchedKe y);
525 }
526 return create_unstretched_bitmap_texture(ctx, bmp, unstretchedKey);
527 }
528
529 bool GrIsImageInCache(const GrContext* ctx, uint32_t imageID, const SkIRect& sub set, 506 bool GrIsImageInCache(const GrContext* ctx, uint32_t imageID, const SkIRect& sub set,
530 GrTexture* nativeTexture, const GrTextureParams* params) { 507 GrTexture* nativeTexture, const GrTextureParams& params) {
531 Stretch stretch; 508 SkGrStretch stretch;
532 get_stretch(ctx, subset.width(), subset.height(), params, &stretch); 509 get_stretch(*ctx->caps(), subset.width(), subset.height(), params, &stretch) ;
533 510
534 // Handle the case where the bitmap/image is explicitly texture backed. 511 // Handle the case where the bitmap/image is explicitly texture backed.
535 if (nativeTexture) { 512 if (nativeTexture) {
536 if (Stretch::kNone_Type == stretch.fType) { 513 if (SkGrStretch::kNone_Type == stretch.fType) {
537 return true; 514 return true;
538 } 515 }
539 const GrUniqueKey& key = nativeTexture->getUniqueKey(); 516 const GrUniqueKey& key = nativeTexture->getUniqueKey();
540 if (!key.isValid()) { 517 if (!key.isValid()) {
541 return false; 518 return false;
542 } 519 }
543 GrUniqueKey stretchedKey; 520 GrUniqueKey stretchedKey;
544 make_stretched_key(key, stretch, &stretchedKey); 521 GrMakeStretchedKey(key, stretch, &stretchedKey);
545 return ctx->textureProvider()->existsTextureWithUniqueKey(stretchedKey); 522 return ctx->textureProvider()->existsTextureWithUniqueKey(stretchedKey);
546 } 523 }
547 524
548 GrUniqueKey key, stretchedKey; 525 GrUniqueKey key, stretchedKey;
549 make_image_keys(imageID, subset, stretch, &key, &stretchedKey); 526 make_image_keys(imageID, subset, stretch, &key, &stretchedKey);
550 return ctx->textureProvider()->existsTextureWithUniqueKey( 527 return ctx->textureProvider()->existsTextureWithUniqueKey(
551 (Stretch::kNone_Type == stretch.fType) ? key : stretchedKey); 528 (SkGrStretch::kNone_Type == stretch.fType) ? key : stretchedKey);
552 } 529 }
553 530
554 bool GrIsBitmapInCache(const GrContext* ctx, const SkBitmap& bitmap, 531 static GrTexture* generate_mipmaps(const SkBitmap& bitmap,
555 const GrTextureParams* params) { 532 GrContext* ctx) {
556 if (bitmap.isVolatile()) { 533 // Make sure the value of the int fits inside a uint32_t
557 return false; // we don't cache volatile bitmaps. 534 if (bitmap.width() <= 0 && bitmap.height() <= 0) {
535 return nullptr;
558 } 536 }
559 return GrIsImageInCache(ctx, bitmap.getGenerationID(), bitmap.getSubset(), b itmap.getTexture(), 537 SkASSERT(sizeof(int) <= sizeof(uint32_t));
560 params); 538 const uint32_t baseWidth = static_cast<uint32_t>(bitmap.width());
539 const uint32_t baseHeight = static_cast<uint32_t>(bitmap.height());
540
541 // OpenGL's spec requires that each mipmap level has height/width equal to
542 // max(1, floor(original_height / 2^i)
543 // (or original_height) where i is the mipmap level.
544 // Keep scaling down until both axes are size 1.
545
546 const uint32_t largestAxis = SkTMax(baseWidth, baseHeight);
547 const int leadingZeros = SkCLZ(largestAxis);
548 // If the value 00011010 has 3 leading 0s, it has 5 significant bits
549 // (the bits which are not leading zeros)
550 const int significantBits = (sizeof(uint32_t) * 8) - leadingZeros;
551 if (significantBits < 0)
552 {
553 return nullptr;
554 }
555 const uint32_t unsignedSignificantBits = static_cast<uint32_t>(significantBi ts);
556 const uint32_t mipLevelCount = unsignedSignificantBits;
557
558 GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(bitmap.info());
559 const bool isMipMapped = mipLevelCount > 1;
560 desc.fIsMipMapped = isMipMapped;
561
562 /*
563 SkAutoPixmapUnlock srcUnlocker;
564 if (!bitmap.requestLock(&srcUnlocker)) {
565 return nullptr;
566 }
567 const SkPixmap& srcPixmap = srcUnlocker.pixmap();
568 if (nullptr == srcPixmap.addr()) {
569 return nullptr;
570 }
571 */
572
573 SkTArray<SkMipMapLevel> texels(mipLevelCount);
574 //SkMipMapLevel baseLevel(srcPixmap.addr(), bitmap.rowBytes(), baseWidth, ba seHeight);
575 SkMipMapLevel baseLevel(bitmap.getPixels(), bitmap.rowBytes(), baseWidth, ba seHeight);
576 texels.push_back(baseLevel);
577
578 SkTArray<SkBitmap> mipLevelBitmaps(mipLevelCount - 1);
579 mipLevelBitmaps.push_back_n(mipLevelCount - 1);
580
581 for (uint32_t i = 1; i < mipLevelCount; i++) {
582 SkBitmap& currentMipBitmap = mipLevelBitmaps[i - 1];
583
584 uint32_t twoToTheMipLevel = 1 << (i + 1);
585 uint32_t currentMipLevelWidth = SkTMax(1u, baseWidth / twoToTheMipLevel) ;
586 uint32_t currentMipLevelHeight = SkTMax(1u, baseHeight / twoToTheMipLeve l);
587
588 SkImageInfo info = SkImageInfo::Make(currentMipLevelWidth, currentMipLev elHeight,
589 currentMipBitmap.colorType(),
590 bitmap.alphaType());
591 if (!currentMipBitmap.tryAllocPixels(info))
592 {
593 return nullptr;
594 }
595
596 SkCanvas canvas(currentMipBitmap);
597 canvas.clear(SK_ColorTRANSPARENT);
598 canvas.drawBitmap(bitmap, SkIntToScalar(0), SkIntToScalar(0));
599
600 /*
601 SkAutoPixmapUnlock mipUnlocker;
602 if (!currentMipBitmap.requestLock(&mipUnlocker)) {
603 return nullptr;
604 }
605 const SkPixmap& mipPixmap = mipUnlocker.pixmap();
606 if (nullptr == mipPixmap.addr()) {
607 return nullptr;
608 }
609 */
610
611 SkMipMapLevel currentMipLevel(currentMipBitmap.getPixels(),
612 //SkMipMapLevel currentMipLevel(mipPixmap.addr(),
613 currentMipBitmap.rowBytes(),
614 currentMipLevelWidth, currentMipLevelHeigh t);
615 texels.push_back(currentMipLevel);
616 }
617
618
619 GrUniqueKey unstretchedKey;
620 make_unstretched_key(&unstretchedKey, bitmap.getGenerationID(), bitmap.getSu bset(), isMipMapped);
621
622 return GrCreateTextureForPixels(ctx, unstretchedKey, desc, bitmap.pixelRef() , texels);
561 } 623 }
562 624
563 GrTexture* GrRefCachedBitmapTexture(GrContext* ctx,
564 const SkBitmap& bitmap,
565 const GrTextureParams* params) {
566 625
567 Stretch stretch; 626 class Bitmap_GrTextureMaker : public GrTextureMaker {
568 get_stretch(ctx, bitmap.width(), bitmap.height(), params, &stretch); 627 public:
628 Bitmap_GrTextureMaker(const SkBitmap& bitmap)
629 : INHERITED(bitmap.width(), bitmap.height())
630 , fBitmap(bitmap)
631 {}
569 632
570 GrTexture* result = bitmap.getTexture(); 633 protected:
571 if (result) { 634 GrTexture* onRefUnstretchedTexture(GrContext* ctx, const GrTextureParams* pa rams) override {
572 if (Stretch::kNone_Type == stretch.fType) { 635 GrTexture* texture = fBitmap.getTexture();
573 return SkRef(result); 636
637 if (params && params->filterMode() == GrTextureParams::kMipMap_FilterMod e) {
638 return generate_mipmaps(fBitmap, ctx);
574 } 639 }
575 GrUniqueKey stretchedKey; 640
576 // Don't create a key for the resized version if the bmp is volatile. 641 if (texture) {
577 if (!bitmap.isVolatile()) { 642 return SkRef(texture);
578 const GrUniqueKey& key = result->getUniqueKey();
579 if (key.isValid()) {
580 make_stretched_key(key, stretch, &stretchedKey);
581 GrTexture* stretched =
582 ctx->textureProvider()->findAndRefTextureByUniqueKey(stretch edKey);
583 if (stretched) {
584 return stretched;
585 }
586 }
587 } 643 }
588 return stretch_texture(result, stretch, bitmap.pixelRef(), stretchedKey) ;
589 }
590 644
591 GrUniqueKey key, resizedKey; 645 GrUniqueKey unstretchedKey;
646 make_unstretched_key(&unstretchedKey, fBitmap.getGenerationID(), fBitmap .getSubset());
592 647
593 if (!bitmap.isVolatile()) { 648 GrTexture* result = ctx->textureProvider()->findAndRefTextureByUniqueKey (unstretchedKey);
594 // If the bitmap isn't changing try to find a cached copy first.
595 make_image_keys(bitmap.getGenerationID(), bitmap.getSubset(), stretch, & key, &resizedKey);
596
597 result = ctx->textureProvider()->findAndRefTextureByUniqueKey(
598 resizedKey.isValid() ? resizedKey : key);
599 if (result) { 649 if (result) {
600 return result; 650 return result;
601 } 651 }
652 return create_unstretched_bitmap_texture(ctx, fBitmap, unstretchedKey);
602 } 653 }
603 654
604 result = create_bitmap_texture(ctx, bitmap, stretch, key, resizedKey); 655 bool onMakeStretchedKey(const SkGrStretch& stretch, GrUniqueKey* stretchedKe y) override {
605 if (result) { 656 if (fBitmap.isVolatile()) {
606 return result; 657 return false;
658 }
659
660 GrUniqueKey unstretchedKey;
661 make_unstretched_key(&unstretchedKey, fBitmap.getGenerationID(), fBitmap .getSubset());
662 return GrMakeStretchedKey(unstretchedKey, stretch, stretchedKey);
607 } 663 }
608 664
609 SkErrorInternals::SetError( kInternalError_SkError, 665 void onNotifyStretchCached(const GrUniqueKey& stretchedKey) override {
610 "---- failed to create texture for cache [%d %d] \n", 666 fBitmap.pixelRef()->addGenIDChangeListener(new BitmapInvalidator(stretch edKey));
611 bitmap.width(), bitmap.height()); 667 }
612 668
613 return nullptr; 669 bool onGetROBitmap(SkBitmap* bitmap) override {
614 } 670 *bitmap = fBitmap;
671 return true;
672 }
615 673
616 // TODO: make this be the canonical signature, and turn the version that takes G rTextureParams* 674 private:
617 // into a wrapper that contains the inverse of these tables. 675 const SkBitmap fBitmap;
618 GrTexture* GrRefCachedBitmapTexture(GrContext* ctx,
619 const SkBitmap& bitmap,
620 SkImageUsageType usage) {
621 // Just need a params that will trigger the correct cache key / etc, since t he usage doesn't
622 // tell us the specifics about filter level or specific tiling.
623 676
624 const SkShader::TileMode tiles[] = { 677 typedef GrTextureMaker INHERITED;
625 SkShader::kClamp_TileMode, // kUntiled_SkImageUsageType 678 };
626 SkShader::kRepeat_TileMode, // kTiled_Unfiltered_SkImageUsageType
627 SkShader::kRepeat_TileMode, // kTiled_Filtered_SkImageUsageType
628 };
629 679
630 const GrTextureParams::FilterMode filters[] = { 680 GrTexture* GrRefCachedBitmapTexture(GrContext* ctx, const SkBitmap& bitmap,
631 GrTextureParams::kNone_FilterMode, // kUntiled_SkImageUsageType 681 const GrTextureParams& params) {
632 GrTextureParams::kNone_FilterMode, // kTiled_Unfiltered_SkImageUsag eType 682 return Bitmap_GrTextureMaker(bitmap).refCachedTexture(ctx, params);
633 GrTextureParams::kBilerp_FilterMode, // kTiled_Filtered_SkImageUsageT ype
634 };
635
636 GrTextureParams params(tiles[usage], filters[usage]);
637 return GrRefCachedBitmapTexture(ctx, bitmap, &params);
638 } 683 }
639 684
640 /////////////////////////////////////////////////////////////////////////////// 685 ///////////////////////////////////////////////////////////////////////////////
641 686
642 // alphatype is ignore for now, but if GrPixelConfig is expanded to encompass 687 // alphatype is ignore for now, but if GrPixelConfig is expanded to encompass
643 // alpha info, that will be considered. 688 // alpha info, that will be considered.
644 GrPixelConfig SkImageInfo2GrPixelConfig(SkColorType ct, SkAlphaType, SkColorProf ileType pt) { 689 GrPixelConfig SkImageInfo2GrPixelConfig(SkColorType ct, SkAlphaType, SkColorProf ileType pt) {
645 switch (ct) { 690 switch (ct) {
646 case kUnknown_SkColorType: 691 case kUnknown_SkColorType:
647 return kUnknown_GrPixelConfig; 692 return kUnknown_GrPixelConfig;
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
699 } 744 }
700 if (ctOut) { 745 if (ctOut) {
701 *ctOut = ct; 746 *ctOut = ct;
702 } 747 }
703 if (ptOut) { 748 if (ptOut) {
704 *ptOut = pt; 749 *ptOut = pt;
705 } 750 }
706 return true; 751 return true;
707 } 752 }
708 753
709 ///////////////////////////////////////////////////////////////////////////////
710 754
711 bool SkPaint2GrPaintNoShader(GrContext* context, const SkPaint& skPaint, GrColor paintColor, 755 //////////////////////////////////////////////////////////////////////////////// ////////////////
712 bool constantColor, GrPaint* grPaint) {
713 756
757 static inline bool blend_requires_shader(const SkXfermode::Mode mode, bool primi tiveIsSrc) {
758 if (primitiveIsSrc) {
759 return SkXfermode::kSrc_Mode != mode;
760 } else {
761 return SkXfermode::kDst_Mode != mode;
762 }
763 }
764
765 static inline bool skpaint_to_grpaint_impl(GrContext* context,
766 const SkPaint& skPaint,
767 const SkMatrix& viewM,
768 const GrFragmentProcessor** shaderPro cessor,
769 SkXfermode::Mode* primColorMode,
770 bool primitiveIsSrc,
771 GrPaint* grPaint) {
714 grPaint->setAntiAlias(skPaint.isAntiAlias()); 772 grPaint->setAntiAlias(skPaint.isAntiAlias());
715 773
774 // Setup the initial color considering the shader, the SkPaint color, and th e presence or not
775 // of per-vertex colors.
776 SkAutoTUnref<const GrFragmentProcessor> aufp;
777 const GrFragmentProcessor* shaderFP = nullptr;
778 if (!primColorMode || blend_requires_shader(*primColorMode, primitiveIsSrc)) {
779 if (shaderProcessor) {
780 shaderFP = *shaderProcessor;
781 } else if (const SkShader* shader = skPaint.getShader()) {
782 aufp.reset(shader->asFragmentProcessor(context, viewM, nullptr,
783 skPaint.getFilterQuality()));
784 shaderFP = aufp;
785 if (!shaderFP) {
786 return false;
787 }
788 }
789 }
790
791 // Set this in below cases if the output of the shader/paint-color/paint-alp ha/primXfermode is
792 // a known constant value. In that case we can simply apply a color filter d uring this
793 // conversion without converting the color filter to a GrFragmentProcessor.
794 bool applyColorFilterToPaintColor = false;
795 if (shaderFP) {
796 if (primColorMode) {
797 // There is a blend between the primitive color and the shader color . The shader sees
798 // the opaque paint color. The shader's output is blended using the provided mode by
799 // the primitive color. The blended color is then modulated by the p aint's alpha.
800
801 // The geometry processor will insert the primitive color to start t he color chain, so
802 // the GrPaint color will be ignored.
803
804 GrColor shaderInput = SkColorToOpaqueGrColor(skPaint.getColor());
805
806 shaderFP = GrFragmentProcessor::OverrideInput(shaderFP, shaderInput) ;
807 aufp.reset(shaderFP);
808
809 if (primitiveIsSrc) {
810 shaderFP = GrXfermodeFragmentProcessor::CreateFromDstProcessor(s haderFP,
811 * primColorMode);
812 } else {
813 shaderFP = GrXfermodeFragmentProcessor::CreateFromSrcProcessor(s haderFP,
814 * primColorMode);
815 }
816 aufp.reset(shaderFP);
817 // The above may return null if compose results in a pass through of the prim color.
818 if (shaderFP) {
819 grPaint->addColorFragmentProcessor(shaderFP);
820 }
821
822 GrColor paintAlpha = SkColorAlphaToGrColor(skPaint.getColor());
823 if (GrColor_WHITE != paintAlpha) {
824 grPaint->addColorFragmentProcessor(GrConstColorProcessor::Create (
825 paintAlpha, GrConstColorProcessor::kModulateRGBA_InputMode)) ->unref();
826 }
827 } else {
828 // The shader's FP sees the paint unpremul color
829 grPaint->setColor(SkColorToUnpremulGrColor(skPaint.getColor()));
830 grPaint->addColorFragmentProcessor(shaderFP);
831 }
832 } else {
833 if (primColorMode) {
834 // There is a blend between the primitive color and the paint color. The blend considers
835 // the opaque paint color. The paint's alpha is applied to the post- blended color.
836 SkAutoTUnref<const GrFragmentProcessor> processor(
837 GrConstColorProcessor::Create(SkColorToOpaqueGrColor(skPaint.get Color()),
838 GrConstColorProcessor::kIgnore_Inp utMode));
839 if (primitiveIsSrc) {
840 processor.reset(GrXfermodeFragmentProcessor::CreateFromDstProces sor(processor,
841 *primColorMode));
842 } else {
843 processor.reset(GrXfermodeFragmentProcessor::CreateFromSrcProces sor(processor,
844 *primColorMode));
845
846 }
847 if (processor) {
848 grPaint->addColorFragmentProcessor(processor);
849 }
850
851 grPaint->setColor(SkColorToOpaqueGrColor(skPaint.getColor()));
852
853 GrColor paintAlpha = SkColorAlphaToGrColor(skPaint.getColor());
854 if (GrColor_WHITE != paintAlpha) {
855 grPaint->addColorFragmentProcessor(GrConstColorProcessor::Create (
856 paintAlpha, GrConstColorProcessor::kModulateRGBA_InputMode)) ->unref();
857 }
858 } else {
859 // No shader, no primitive color.
860 grPaint->setColor(SkColorToPremulGrColor(skPaint.getColor()));
861 applyColorFilterToPaintColor = true;
862 }
863 }
864
865 SkColorFilter* colorFilter = skPaint.getColorFilter();
866 if (colorFilter) {
867 if (applyColorFilterToPaintColor) {
868 grPaint->setColor(SkColorToPremulGrColor(colorFilter->filterColor(sk Paint.getColor())));
869 } else {
870 SkAutoTUnref<const GrFragmentProcessor> cfFP(
871 colorFilter->asFragmentProcessor(context));
872 if (cfFP) {
873 grPaint->addColorFragmentProcessor(cfFP);
874 } else {
875 return false;
876 }
877 }
878 }
879
716 SkXfermode* mode = skPaint.getXfermode(); 880 SkXfermode* mode = skPaint.getXfermode();
717 GrXPFactory* xpFactory = nullptr; 881 GrXPFactory* xpFactory = nullptr;
718 if (!SkXfermode::AsXPFactory(mode, &xpFactory)) { 882 if (!SkXfermode::AsXPFactory(mode, &xpFactory)) {
719 // Fall back to src-over 883 // Fall back to src-over
720 // return false here? 884 // return false here?
721 xpFactory = GrPorterDuffXPFactory::Create(SkXfermode::kSrcOver_Mode); 885 xpFactory = GrPorterDuffXPFactory::Create(SkXfermode::kSrcOver_Mode);
722 } 886 }
723 SkASSERT(xpFactory); 887 SkASSERT(xpFactory);
724 grPaint->setXPFactory(xpFactory)->unref(); 888 grPaint->setXPFactory(xpFactory)->unref();
725 889
726 //set the color of the paint to the one of the parameter
727 grPaint->setColor(paintColor);
728
729 SkColorFilter* colorFilter = skPaint.getColorFilter();
730 if (colorFilter) {
731 // if the source color is a constant then apply the filter here once rat her than per pixel
732 // in a shader.
733 if (constantColor) {
734 SkColor filtered = colorFilter->filterColor(skPaint.getColor());
735 grPaint->setColor(SkColor2GrColor(filtered));
736 } else {
737 SkTDArray<const GrFragmentProcessor*> array;
738 // return false if failed?
739 if (colorFilter->asFragmentProcessors(context, grPaint->getProcessor DataManager(),
740 &array)) {
741 for (int i = 0; i < array.count(); ++i) {
742 grPaint->addColorFragmentProcessor(array[i]);
743 array[i]->unref();
744 }
745 }
746 }
747 }
748
749 #ifndef SK_IGNORE_GPU_DITHER 890 #ifndef SK_IGNORE_GPU_DITHER
750 if (skPaint.isDither() && grPaint->numColorFragmentProcessors() > 0) { 891 if (skPaint.isDither() && grPaint->numColorFragmentProcessors() > 0) {
751 grPaint->addColorFragmentProcessor(GrDitherEffect::Create())->unref(); 892 grPaint->addColorFragmentProcessor(GrDitherEffect::Create())->unref();
752 } 893 }
753 #endif 894 #endif
754 return true; 895 return true;
755 } 896 }
756 897
757 bool SkPaint2GrPaint(GrContext* context,const SkPaint& skPaint, const SkMatrix& viewM, 898 bool SkPaintToGrPaint(GrContext* context, const SkPaint& skPaint, const SkMatrix & viewM,
758 bool constantColor, GrPaint* grPaint) { 899 GrPaint* grPaint) {
759 SkShader* shader = skPaint.getShader(); 900 return skpaint_to_grpaint_impl(context, skPaint, viewM, nullptr, nullptr, fa lse, grPaint);
760 if (nullptr == shader) { 901 }
761 return SkPaint2GrPaintNoShader(context, skPaint, SkColor2GrColor(skPaint .getColor()),
762 constantColor, grPaint);
763 }
764 902
765 GrColor paintColor = SkColor2GrColor(skPaint.getColor()); 903 /** Replaces the SkShader (if any) on skPaint with the passed in GrFragmentProce ssor. */
766 904 bool SkPaintToGrPaintReplaceShader(GrContext* context,
767 const GrFragmentProcessor* fp = shader->asFragmentProcessor(context, viewM, NULL, 905 const SkPaint& skPaint,
768 skPaint.getFilterQuality(), grPaint->getProcessorDataManager()); 906 const GrFragmentProcessor* shaderFP,
769 if (!fp) { 907 GrPaint* grPaint) {
908 if (!shaderFP) {
770 return false; 909 return false;
771 } 910 }
772 grPaint->addColorFragmentProcessor(fp)->unref(); 911 return skpaint_to_grpaint_impl(context, skPaint, SkMatrix::I(), &shaderFP, n ullptr, false,
773 constantColor = false; 912 grPaint);
913 }
774 914
775 // The grcolor is automatically set when calling asFragmentProcessor. 915 /** Ignores the SkShader (if any) on skPaint. */
776 // If the shader can be seen as an effect it returns true and adds its effec t to the grpaint. 916 bool SkPaintToGrPaintNoShader(GrContext* context,
777 return SkPaint2GrPaintNoShader(context, skPaint, paintColor, constantColor, grPaint); 917 const SkPaint& skPaint,
918 GrPaint* grPaint) {
919 // Use a ptr to a nullptr to to indicate that the SkShader is ignored and no t replaced.
920 static const GrFragmentProcessor* kNullShaderFP = nullptr;
921 static const GrFragmentProcessor** kIgnoreShader = &kNullShaderFP;
922 return skpaint_to_grpaint_impl(context, skPaint, SkMatrix::I(), kIgnoreShade r, nullptr, false,
923 grPaint);
778 } 924 }
779 925
926 /** Blends the SkPaint's shader (or color if no shader) with a per-primitive col or which must
927 be setup as a vertex attribute using the specified SkXfermode::Mode. */
928 bool SkPaintToGrPaintWithXfermode(GrContext* context,
929 const SkPaint& skPaint,
930 const SkMatrix& viewM,
931 SkXfermode::Mode primColorMode,
932 bool primitiveIsSrc,
933 GrPaint* grPaint) {
934 return skpaint_to_grpaint_impl(context, skPaint, viewM, nullptr, &primColorM ode, primitiveIsSrc,
935 grPaint);
936 }
937
938
939 //////////////////////////////////////////////////////////////////////////////// ////////////////
940
780 SkImageInfo GrMakeInfoFromTexture(GrTexture* tex, int w, int h, bool isOpaque) { 941 SkImageInfo GrMakeInfoFromTexture(GrTexture* tex, int w, int h, bool isOpaque) {
781 #ifdef SK_DEBUG 942 #ifdef SK_DEBUG
782 const GrSurfaceDesc& desc = tex->desc(); 943 const GrSurfaceDesc& desc = tex->desc();
783 SkASSERT(w <= desc.fWidth); 944 SkASSERT(w <= desc.fWidth);
784 SkASSERT(h <= desc.fHeight); 945 SkASSERT(h <= desc.fHeight);
785 #endif 946 #endif
786 const GrPixelConfig config = tex->config(); 947 const GrPixelConfig config = tex->config();
787 SkColorType ct; 948 SkColorType ct;
788 SkAlphaType at = isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType; 949 SkAlphaType at = isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType;
789 if (!GrPixelConfig2ColorAndProfileType(config, &ct, nullptr)) { 950 if (!GrPixelConfig2ColorAndProfileType(config, &ct, nullptr)) {
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
833 SkErrorInternals::SetError( kInvalidPaint_SkError, 994 SkErrorInternals::SetError( kInvalidPaint_SkError,
834 "Sorry, I don't understand the filtering " 995 "Sorry, I don't understand the filtering "
835 "mode you asked for. Falling back to " 996 "mode you asked for. Falling back to "
836 "MIPMaps."); 997 "MIPMaps.");
837 textureFilterMode = GrTextureParams::kMipMap_FilterMode; 998 textureFilterMode = GrTextureParams::kMipMap_FilterMode;
838 break; 999 break;
839 1000
840 } 1001 }
841 return textureFilterMode; 1002 return textureFilterMode;
842 } 1003 }
1004
1005 //////////////////////////////////////////////////////////////////////////////// ////////////////
1006
1007 GrTexture* GrTextureMaker::refCachedTexture(GrContext* ctx, const GrTextureParam s& params) {
1008 SkGrStretch stretch;
1009 get_stretch(*ctx->caps(), this->width(), this->height(), params, &stretch);
1010
1011 if (SkGrStretch::kNone_Type == stretch.fType) {
1012 return this->onRefUnstretchedTexture(ctx, &params);
1013 }
1014
1015 GrUniqueKey stretchedKey;
1016 if (this->onMakeStretchedKey(stretch, &stretchedKey)) {
1017 GrTexture* result = ctx->textureProvider()->findAndRefTextureByUniqueKey (stretchedKey);
1018 if (result) {
1019 return result;
1020 }
1021 }
1022
1023 GrTexture* result = this->onGenerateStretchedTexture(ctx, stretch, &params);
1024 if (!result) {
1025 return nullptr;
1026 }
1027
1028 if (stretchedKey.isValid()) {
1029 ctx->textureProvider()->assignUniqueKeyToTexture(stretchedKey, result);
1030 this->onNotifyStretchCached(stretchedKey);
1031 }
1032 return result;
1033 }
1034
1035 GrTexture* GrTextureMaker::onGenerateStretchedTexture(GrContext* ctx, const SkGr Stretch& stretch, const GrTextureParams* params) {
1036 if (this->width() < ctx->caps()->minTextureSize() ||
1037 this->height() < ctx->caps()->minTextureSize())
1038 {
1039 // we can't trust our ability to use HW to perform the stretch, so we re quest
1040 // a raster instead, and perform the stretch on the CPU.
1041 SkBitmap bitmap;
1042 if (!this->onGetROBitmap(&bitmap)) {
1043 return nullptr;
1044 }
1045 SkBitmap stretchedBmp = stretch_on_cpu(bitmap, stretch);
1046 return create_unstretched_bitmap_texture(ctx, stretchedBmp, GrUniqueKey( ));
1047 } else {
1048 SkAutoTUnref<GrTexture> unstretched(this->onRefUnstretchedTexture(ctx, p arams));
1049 if (!unstretched) {
1050 return nullptr;
1051 }
1052 return stretch_texture(unstretched, stretch, nullptr, GrUniqueKey());
1053 }
1054 }
OLDNEW
« include/gpu/GrContext.h ('K') | « src/gpu/SkGpuDevice.cpp ('k') | src/gpu/SkGrPixelRef.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698