OLD | NEW |
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 "SkGr.h" | 8 #include "SkGr.h" |
9 | 9 |
10 #include "GrCaps.h" | 10 #include "GrCaps.h" |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
81 for (int y = 0; y < bitmap.height(); y++) { | 81 for (int y = 0; y < bitmap.height(); y++) { |
82 memcpy(dst, src, width); | 82 memcpy(dst, src, width); |
83 src += rowBytes; | 83 src += rowBytes; |
84 dst += width; | 84 dst += width; |
85 } | 85 } |
86 } | 86 } |
87 } | 87 } |
88 | 88 |
89 //////////////////////////////////////////////////////////////////////////////// | 89 //////////////////////////////////////////////////////////////////////////////// |
90 | 90 |
91 enum Stretch { | 91 struct Stretch { |
92 kNo_Stretch, | 92 enum Type { |
93 kBilerp_Stretch, | 93 kNone_Type, |
94 kNearest_Stretch | 94 kBilerp_Type, |
| 95 kNearest_Type |
| 96 } fType; |
| 97 int fWidth; |
| 98 int fHeight; |
95 }; | 99 }; |
96 | 100 |
97 static Stretch get_stretch_type(const GrContext* ctx, int width, int height, | 101 static void get_stretch(const GrContext* ctx, int width, int height, |
98 const GrTextureParams* params) { | 102 const GrTextureParams* params, Stretch* stretch) { |
99 if (params && params->isTiled()) { | 103 stretch->fType = Stretch::kNone_Type; |
100 if (!ctx->caps()->npotTextureTileSupport() && (!SkIsPow2(width) || !SkIs
Pow2(height))) { | 104 bool doStretch = false; |
101 switch(params->filterMode()) { | 105 if (params && params->isTiled() && !ctx->caps()->npotTextureTileSupport() && |
102 case GrTextureParams::kNone_FilterMode: | 106 (!SkIsPow2(width) || !SkIsPow2(height))) { |
103 return kNearest_Stretch; | 107 doStretch = true; |
104 case GrTextureParams::kBilerp_FilterMode: | 108 stretch->fWidth = GrNextPow2(width); |
105 case GrTextureParams::kMipMap_FilterMode: | 109 stretch->fHeight = GrNextPow2(height); |
106 return kBilerp_Stretch; | 110 } else if (width < ctx->caps()->minTextureSize() || |
107 } | 111 height < ctx->caps()->minTextureSize()) { |
| 112 doStretch = true; |
| 113 stretch->fWidth = SkTMax(width, ctx->caps()->minTextureSize()); |
| 114 stretch->fHeight = SkTMax(height, ctx->caps()->minTextureSize()); |
| 115 } |
| 116 if (doStretch) { |
| 117 switch(params->filterMode()) { |
| 118 case GrTextureParams::kNone_FilterMode: |
| 119 stretch->fType = Stretch::kNearest_Type; |
| 120 break; |
| 121 case GrTextureParams::kBilerp_FilterMode: |
| 122 case GrTextureParams::kMipMap_FilterMode: |
| 123 stretch->fType = Stretch::kBilerp_Type; |
| 124 break; |
108 } | 125 } |
| 126 } else { |
| 127 stretch->fWidth = -1; |
| 128 stretch->fHeight = -1; |
| 129 stretch->fType = Stretch::kNone_Type; |
109 } | 130 } |
110 return kNo_Stretch; | |
111 } | 131 } |
112 | 132 |
113 static bool make_stretched_key(const GrUniqueKey& origKey, Stretch stretch, | 133 static bool make_stretched_key(const GrUniqueKey& origKey, const Stretch& stretc
h, |
114 GrUniqueKey* stretchedKey) { | 134 GrUniqueKey* stretchedKey) { |
115 if (origKey.isValid() && kNo_Stretch != stretch) { | 135 if (origKey.isValid() && Stretch::kNone_Type != stretch.fType) { |
| 136 uint32_t width = SkToU16(stretch.fWidth); |
| 137 uint32_t height = SkToU16(stretch.fHeight); |
116 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain()
; | 138 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain()
; |
117 GrUniqueKey::Builder builder(stretchedKey, origKey, kDomain, 1); | 139 GrUniqueKey::Builder builder(stretchedKey, origKey, kDomain, 3); |
118 builder[0] = stretch; | 140 builder[0] = stretch.fType; |
| 141 builder[1] = width | (height << 16); |
119 builder.finish(); | 142 builder.finish(); |
120 return true; | 143 return true; |
121 } | 144 } |
122 SkASSERT(!stretchedKey->isValid()); | 145 SkASSERT(!stretchedKey->isValid()); |
123 return false; | 146 return false; |
124 } | 147 } |
125 | 148 |
126 static void make_unstretched_key(const SkBitmap& bitmap, GrUniqueKey* key) { | 149 static void make_unstretched_key(const SkBitmap& bitmap, GrUniqueKey* key) { |
127 // Our id includes the offset, width, and height so that bitmaps created by
extractSubset() | 150 // Our id includes the offset, width, and height so that bitmaps created by
extractSubset() |
128 // are unique. | 151 // are unique. |
129 uint32_t genID = bitmap.getGenerationID(); | 152 uint32_t genID = bitmap.getGenerationID(); |
130 SkIPoint origin = bitmap.pixelRefOrigin(); | 153 SkIPoint origin = bitmap.pixelRefOrigin(); |
131 uint32_t width = SkToU16(bitmap.width()); | 154 uint32_t width = SkToU16(bitmap.width()); |
132 uint32_t height = SkToU16(bitmap.height()); | 155 uint32_t height = SkToU16(bitmap.height()); |
133 | 156 |
134 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); | 157 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); |
135 GrUniqueKey::Builder builder(key, kDomain, 4); | 158 GrUniqueKey::Builder builder(key, kDomain, 4); |
136 builder[0] = genID; | 159 builder[0] = genID; |
137 builder[1] = origin.fX; | 160 builder[1] = origin.fX; |
138 builder[2] = origin.fY; | 161 builder[2] = origin.fY; |
139 builder[3] = width | (height << 16); | 162 builder[3] = width | (height << 16); |
140 } | 163 } |
141 | 164 |
142 static void make_bitmap_keys(const SkBitmap& bitmap, | 165 static void make_bitmap_keys(const SkBitmap& bitmap, |
143 Stretch stretch, | 166 const Stretch& stretch, |
144 GrUniqueKey* key, | 167 GrUniqueKey* key, |
145 GrUniqueKey* stretchedKey) { | 168 GrUniqueKey* stretchedKey) { |
146 make_unstretched_key(bitmap, key); | 169 make_unstretched_key(bitmap, key); |
147 if (kNo_Stretch != stretch) { | 170 if (Stretch::kNone_Type != stretch.fType) { |
148 make_stretched_key(*key, stretch, stretchedKey); | 171 make_stretched_key(*key, stretch, stretchedKey); |
149 } | 172 } |
150 } | 173 } |
151 | 174 |
152 static void generate_bitmap_texture_desc(const SkBitmap& bitmap, GrSurfaceDesc*
desc) { | 175 static void generate_bitmap_texture_desc(const SkBitmap& bitmap, GrSurfaceDesc*
desc) { |
153 desc->fFlags = kNone_GrSurfaceFlags; | 176 desc->fFlags = kNone_GrSurfaceFlags; |
154 desc->fWidth = bitmap.width(); | 177 desc->fWidth = bitmap.width(); |
155 desc->fHeight = bitmap.height(); | 178 desc->fHeight = bitmap.height(); |
156 desc->fConfig = SkImageInfo2GrPixelConfig(bitmap.info()); | 179 desc->fConfig = SkImageInfo2GrPixelConfig(bitmap.info()); |
157 desc->fSampleCnt = 0; | 180 desc->fSampleCnt = 0; |
(...skipping 24 matching lines...) Expand all Loading... |
182 size_t rowBytes) { | 205 size_t rowBytes) { |
183 GrTexture* result = ctx->textureProvider()->createTexture(desc, true, pixels
, rowBytes); | 206 GrTexture* result = ctx->textureProvider()->createTexture(desc, true, pixels
, rowBytes); |
184 if (result && optionalKey.isValid()) { | 207 if (result && optionalKey.isValid()) { |
185 BitmapInvalidator* listener = SkNEW_ARGS(BitmapInvalidator, (optionalKey
)); | 208 BitmapInvalidator* listener = SkNEW_ARGS(BitmapInvalidator, (optionalKey
)); |
186 pixelRefForInvalidationNotification->addGenIDChangeListener(listener); | 209 pixelRefForInvalidationNotification->addGenIDChangeListener(listener); |
187 ctx->textureProvider()->assignUniqueKeyToTexture(optionalKey, result); | 210 ctx->textureProvider()->assignUniqueKeyToTexture(optionalKey, result); |
188 } | 211 } |
189 return result; | 212 return result; |
190 } | 213 } |
191 | 214 |
192 // creates a new texture that is the input texture scaled up to the next power o
f two in | 215 // creates a new texture that is the input texture scaled up. If optionalKey is
valid it will be |
193 // width or height. If optionalKey is valid it will be set on the new texture. s
tretch | 216 // set on the new texture. stretch controls whether the scaling is done using ne
arest or bilerp |
194 // controls whether the scaling is done using nearest or bilerp filtering. | 217 // filtering and the size to stretch the texture to. |
195 GrTexture* stretch_texture_to_next_pot(GrTexture* inputTexture, Stretch stretch, | 218 GrTexture* stretch_texture(GrTexture* inputTexture, const Stretch& stretch, |
196 SkPixelRef* pixelRef, | 219 SkPixelRef* pixelRef, |
197 const GrUniqueKey& optionalKey) { | 220 const GrUniqueKey& optionalKey) { |
198 SkASSERT(kNo_Stretch != stretch); | 221 SkASSERT(Stretch::kNone_Type != stretch.fType); |
199 | 222 |
200 GrContext* context = inputTexture->getContext(); | 223 GrContext* context = inputTexture->getContext(); |
201 SkASSERT(context); | 224 SkASSERT(context); |
202 const GrCaps* caps = context->caps(); | 225 const GrCaps* caps = context->caps(); |
203 | 226 |
204 // Either it's a cache miss or the original wasn't cached to begin with. | 227 // Either it's a cache miss or the original wasn't cached to begin with. |
205 GrSurfaceDesc rtDesc = inputTexture->desc(); | 228 GrSurfaceDesc rtDesc = inputTexture->desc(); |
206 rtDesc.fFlags = rtDesc.fFlags | kRenderTarget_GrSurfaceFlag; | 229 rtDesc.fFlags = rtDesc.fFlags | kRenderTarget_GrSurfaceFlag; |
207 rtDesc.fWidth = GrNextPow2(rtDesc.fWidth); | 230 rtDesc.fWidth = stretch.fWidth; |
208 rtDesc.fHeight = GrNextPow2(rtDesc.fHeight); | 231 rtDesc.fHeight = stretch.fHeight; |
209 rtDesc.fConfig = GrMakePixelConfigUncompressed(rtDesc.fConfig); | 232 rtDesc.fConfig = GrMakePixelConfigUncompressed(rtDesc.fConfig); |
210 | 233 |
211 // If the config isn't renderable try converting to either A8 or an 32 bit c
onfig. Otherwise, | 234 // If the config isn't renderable try converting to either A8 or an 32 bit c
onfig. Otherwise, |
212 // fail. | 235 // fail. |
213 if (!caps->isConfigRenderable(rtDesc.fConfig, false)) { | 236 if (!caps->isConfigRenderable(rtDesc.fConfig, false)) { |
214 if (GrPixelConfigIsAlphaOnly(rtDesc.fConfig)) { | 237 if (GrPixelConfigIsAlphaOnly(rtDesc.fConfig)) { |
215 if (caps->isConfigRenderable(kAlpha_8_GrPixelConfig, false)) { | 238 if (caps->isConfigRenderable(kAlpha_8_GrPixelConfig, false)) { |
216 rtDesc.fConfig = kAlpha_8_GrPixelConfig; | 239 rtDesc.fConfig = kAlpha_8_GrPixelConfig; |
217 } else if (caps->isConfigRenderable(kSkia8888_GrPixelConfig, false))
{ | 240 } else if (caps->isConfigRenderable(kSkia8888_GrPixelConfig, false))
{ |
218 rtDesc.fConfig = kSkia8888_GrPixelConfig; | 241 rtDesc.fConfig = kSkia8888_GrPixelConfig; |
(...skipping 15 matching lines...) Expand all Loading... |
234 GrTexture* stretched = create_texture_for_bmp(context, optionalKey, rtDesc,
pixelRef, NULL, 0); | 257 GrTexture* stretched = create_texture_for_bmp(context, optionalKey, rtDesc,
pixelRef, NULL, 0); |
235 | 258 |
236 if (!stretched) { | 259 if (!stretched) { |
237 return NULL; | 260 return NULL; |
238 } | 261 } |
239 GrPaint paint; | 262 GrPaint paint; |
240 | 263 |
241 // If filtering is not desired then we want to ensure all texels in the resa
mpled image are | 264 // If filtering is not desired then we want to ensure all texels in the resa
mpled image are |
242 // copies of texels from the original. | 265 // copies of texels from the original. |
243 GrTextureParams params(SkShader::kClamp_TileMode, | 266 GrTextureParams params(SkShader::kClamp_TileMode, |
244 kBilerp_Stretch == stretch ? GrTextureParams::kBilerp
_FilterMode : | 267 Stretch::kBilerp_Type == stretch.fType ? |
245 GrTextureParams::kNone_F
ilterMode); | 268 GrTextureParams::kBilerp_FilterMode : |
| 269 GrTextureParams::kNone_FilterMode); |
246 paint.addColorTextureProcessor(inputTexture, SkMatrix::I(), params); | 270 paint.addColorTextureProcessor(inputTexture, SkMatrix::I(), params); |
247 | 271 |
248 SkRect rect = SkRect::MakeWH(SkIntToScalar(rtDesc.fWidth), SkIntToScalar(rtD
esc.fHeight)); | 272 SkRect rect = SkRect::MakeWH(SkIntToScalar(rtDesc.fWidth), SkIntToScalar(rtD
esc.fHeight)); |
249 SkRect localRect = SkRect::MakeWH(1.f, 1.f); | 273 SkRect localRect = SkRect::MakeWH(1.f, 1.f); |
250 | 274 |
251 GrDrawContext* drawContext = context->drawContext(); | 275 GrDrawContext* drawContext = context->drawContext(); |
252 if (!drawContext) { | 276 if (!drawContext) { |
253 return NULL; | 277 return NULL; |
254 } | 278 } |
255 | 279 |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
472 if (!bitmap->readyToDraw()) { | 496 if (!bitmap->readyToDraw()) { |
473 return NULL; | 497 return NULL; |
474 } | 498 } |
475 | 499 |
476 return create_texture_for_bmp(ctx, optionalKey, desc, origBitmap.pixelRef(), | 500 return create_texture_for_bmp(ctx, optionalKey, desc, origBitmap.pixelRef(), |
477 bitmap->getPixels(), bitmap->rowBytes()); | 501 bitmap->getPixels(), bitmap->rowBytes()); |
478 } | 502 } |
479 | 503 |
480 static GrTexture* create_bitmap_texture(GrContext* ctx, | 504 static GrTexture* create_bitmap_texture(GrContext* ctx, |
481 const SkBitmap& bmp, | 505 const SkBitmap& bmp, |
482 Stretch stretch, | 506 const Stretch& stretch, |
483 const GrUniqueKey& unstretchedKey, | 507 const GrUniqueKey& unstretchedKey, |
484 const GrUniqueKey& stretchedKey) { | 508 const GrUniqueKey& stretchedKey) { |
485 if (kNo_Stretch != stretch) { | 509 if (Stretch::kNone_Type != stretch.fType) { |
486 SkAutoTUnref<GrTexture> unstretched; | 510 SkAutoTUnref<GrTexture> unstretched; |
487 // Check if we have the unstretched version in the cache, if not create
it. | 511 // Check if we have the unstretched version in the cache, if not create
it. |
488 if (unstretchedKey.isValid()) { | 512 if (unstretchedKey.isValid()) { |
489 unstretched.reset(ctx->textureProvider()->findAndRefTextureByUniqueK
ey(unstretchedKey)); | 513 unstretched.reset(ctx->textureProvider()->findAndRefTextureByUniqueK
ey(unstretchedKey)); |
490 } | 514 } |
491 if (!unstretched) { | 515 if (!unstretched) { |
492 unstretched.reset(create_unstretched_bitmap_texture(ctx, bmp, unstre
tchedKey)); | 516 unstretched.reset(create_unstretched_bitmap_texture(ctx, bmp, unstre
tchedKey)); |
493 if (!unstretched) { | 517 if (!unstretched) { |
494 return NULL; | 518 return NULL; |
495 } | 519 } |
496 } | 520 } |
497 GrTexture* stretched = stretch_texture_to_next_pot(unstretched, stretch,
bmp.pixelRef(), | 521 GrTexture* stretched = stretch_texture(unstretched, stretch, bmp.pixelRe
f(), stretchedKey); |
498 stretchedKey); | |
499 return stretched; | 522 return stretched; |
500 } | 523 } |
501 | 524 |
502 return create_unstretched_bitmap_texture(ctx, bmp, unstretchedKey); | 525 return create_unstretched_bitmap_texture(ctx, bmp, unstretchedKey); |
503 | 526 |
504 } | 527 } |
505 | 528 |
506 bool GrIsBitmapInCache(const GrContext* ctx, | 529 bool GrIsBitmapInCache(const GrContext* ctx, |
507 const SkBitmap& bitmap, | 530 const SkBitmap& bitmap, |
508 const GrTextureParams* params) { | 531 const GrTextureParams* params) { |
509 Stretch stretch = get_stretch_type(ctx, bitmap.width(), bitmap.height(), par
ams); | 532 Stretch stretch; |
| 533 get_stretch(ctx, bitmap.width(), bitmap.height(), params, &stretch); |
510 | 534 |
511 // Handle the case where the bitmap is explicitly texture backed. | 535 // Handle the case where the bitmap is explicitly texture backed. |
512 GrTexture* texture = bitmap.getTexture(); | 536 GrTexture* texture = bitmap.getTexture(); |
513 if (texture) { | 537 if (texture) { |
514 if (kNo_Stretch == stretch) { | 538 if (Stretch::kNone_Type == stretch.fType) { |
515 return true; | 539 return true; |
516 } | 540 } |
517 // No keys for volatile bitmaps. | 541 // No keys for volatile bitmaps. |
518 if (bitmap.isVolatile()) { | 542 if (bitmap.isVolatile()) { |
519 return false; | 543 return false; |
520 } | 544 } |
521 const GrUniqueKey& key = texture->getUniqueKey(); | 545 const GrUniqueKey& key = texture->getUniqueKey(); |
522 if (!key.isValid()) { | 546 if (!key.isValid()) { |
523 return false; | 547 return false; |
524 } | 548 } |
525 GrUniqueKey stretchedKey; | 549 GrUniqueKey stretchedKey; |
526 make_stretched_key(key, stretch, &stretchedKey); | 550 make_stretched_key(key, stretch, &stretchedKey); |
527 return ctx->textureProvider()->existsTextureWithUniqueKey(stretchedKey); | 551 return ctx->textureProvider()->existsTextureWithUniqueKey(stretchedKey); |
528 } | 552 } |
529 | 553 |
530 // We don't cache volatile bitmaps | 554 // We don't cache volatile bitmaps |
531 if (bitmap.isVolatile()) { | 555 if (bitmap.isVolatile()) { |
532 return false; | 556 return false; |
533 } | 557 } |
534 | 558 |
535 GrUniqueKey key, stretchedKey; | 559 GrUniqueKey key, stretchedKey; |
536 make_bitmap_keys(bitmap, stretch, &key, &stretchedKey); | 560 make_bitmap_keys(bitmap, stretch, &key, &stretchedKey); |
537 return ctx->textureProvider()->existsTextureWithUniqueKey( | 561 return ctx->textureProvider()->existsTextureWithUniqueKey( |
538 (kNo_Stretch == stretch) ? key : stretchedKey); | 562 (Stretch::kNone_Type == stretch.fType) ? key : stretchedKey); |
539 } | 563 } |
540 | 564 |
541 GrTexture* GrRefCachedBitmapTexture(GrContext* ctx, | 565 GrTexture* GrRefCachedBitmapTexture(GrContext* ctx, |
542 const SkBitmap& bitmap, | 566 const SkBitmap& bitmap, |
543 const GrTextureParams* params) { | 567 const GrTextureParams* params) { |
544 | 568 |
545 Stretch stretch = get_stretch_type(ctx, bitmap.width(), bitmap.height(), par
ams); | 569 Stretch stretch; |
| 570 get_stretch(ctx, bitmap.width(), bitmap.height(), params, &stretch); |
546 | 571 |
547 GrTexture* result = bitmap.getTexture(); | 572 GrTexture* result = bitmap.getTexture(); |
548 if (result) { | 573 if (result) { |
549 if (kNo_Stretch == stretch) { | 574 if (Stretch::kNone_Type == stretch.fType) { |
550 return SkRef(result); | 575 return SkRef(result); |
551 } | 576 } |
552 GrUniqueKey stretchedKey; | 577 GrUniqueKey stretchedKey; |
553 // Don't create a key for the resized version if the bmp is volatile. | 578 // Don't create a key for the resized version if the bmp is volatile. |
554 if (!bitmap.isVolatile()) { | 579 if (!bitmap.isVolatile()) { |
555 const GrUniqueKey& key = result->getUniqueKey(); | 580 const GrUniqueKey& key = result->getUniqueKey(); |
556 if (key.isValid()) { | 581 if (key.isValid()) { |
557 make_stretched_key(key, stretch, &stretchedKey); | 582 make_stretched_key(key, stretch, &stretchedKey); |
558 GrTexture* stretched = | 583 GrTexture* stretched = |
559 ctx->textureProvider()->findAndRefTextureByUniqueKey(stretch
edKey); | 584 ctx->textureProvider()->findAndRefTextureByUniqueKey(stretch
edKey); |
560 if (stretched) { | 585 if (stretched) { |
561 return stretched; | 586 return stretched; |
562 } | 587 } |
563 } | 588 } |
564 } | 589 } |
565 return stretch_texture_to_next_pot(result, stretch, bitmap.pixelRef(), s
tretchedKey); | 590 return stretch_texture(result, stretch, bitmap.pixelRef(), stretchedKey)
; |
566 } | 591 } |
567 | 592 |
568 GrUniqueKey key, resizedKey; | 593 GrUniqueKey key, resizedKey; |
569 | 594 |
570 if (!bitmap.isVolatile()) { | 595 if (!bitmap.isVolatile()) { |
571 // If the bitmap isn't changing try to find a cached copy first. | 596 // If the bitmap isn't changing try to find a cached copy first. |
572 make_bitmap_keys(bitmap, stretch, &key, &resizedKey); | 597 make_bitmap_keys(bitmap, stretch, &key, &resizedKey); |
573 | 598 |
574 result = ctx->textureProvider()->findAndRefTextureByUniqueKey( | 599 result = ctx->textureProvider()->findAndRefTextureByUniqueKey( |
575 resizedKey.isValid() ? resizedKey : key); | 600 resizedKey.isValid() ? resizedKey : key); |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
767 } | 792 } |
768 return SkImageInfo::Make(w, h, ct, at); | 793 return SkImageInfo::Make(w, h, ct, at); |
769 } | 794 } |
770 | 795 |
771 | 796 |
772 void GrWrapTextureInBitmap(GrTexture* src, int w, int h, bool isOpaque, SkBitmap
* dst) { | 797 void GrWrapTextureInBitmap(GrTexture* src, int w, int h, bool isOpaque, SkBitmap
* dst) { |
773 const SkImageInfo info = GrMakeInfoFromTexture(src, w, h, isOpaque); | 798 const SkImageInfo info = GrMakeInfoFromTexture(src, w, h, isOpaque); |
774 dst->setInfo(info); | 799 dst->setInfo(info); |
775 dst->setPixelRef(SkNEW_ARGS(SkGrPixelRef, (info, src)))->unref(); | 800 dst->setPixelRef(SkNEW_ARGS(SkGrPixelRef, (info, src)))->unref(); |
776 } | 801 } |
OLD | NEW |