OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 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 "SkGpuDevice.h" | 8 #include "SkGpuDevice.h" |
9 | 9 |
10 #include "effects/GrTextureDomainEffect.h" | 10 #include "effects/GrTextureDomainEffect.h" |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
65 : fDevice(NULL) | 65 : fDevice(NULL) |
66 , fTexture(NULL) { | 66 , fTexture(NULL) { |
67 } | 67 } |
68 | 68 |
69 SkAutoCachedTexture(SkGpuDevice* device, | 69 SkAutoCachedTexture(SkGpuDevice* device, |
70 const SkBitmap& bitmap, | 70 const SkBitmap& bitmap, |
71 const GrTextureParams* params, | 71 const GrTextureParams* params, |
72 GrTexture** texture) | 72 GrTexture** texture) |
73 : fDevice(NULL) | 73 : fDevice(NULL) |
74 , fTexture(NULL) { | 74 , fTexture(NULL) { |
75 GrAssert(NULL != texture); | 75 SkASSERT(NULL != texture); |
76 *texture = this->set(device, bitmap, params); | 76 *texture = this->set(device, bitmap, params); |
77 } | 77 } |
78 | 78 |
79 ~SkAutoCachedTexture() { | 79 ~SkAutoCachedTexture() { |
80 if (NULL != fTexture) { | 80 if (NULL != fTexture) { |
81 GrUnlockAndUnrefCachedBitmapTexture(fTexture); | 81 GrUnlockAndUnrefCachedBitmapTexture(fTexture); |
82 } | 82 } |
83 } | 83 } |
84 | 84 |
85 GrTexture* set(SkGpuDevice* device, | 85 GrTexture* set(SkGpuDevice* device, |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
142 | 142 |
143 bool isOpaque; | 143 bool isOpaque; |
144 SkBitmap bitmap; | 144 SkBitmap bitmap; |
145 bitmap.setConfig(grConfig2skConfig(config, &isOpaque), | 145 bitmap.setConfig(grConfig2skConfig(config, &isOpaque), |
146 renderTarget->width(), renderTarget->height()); | 146 renderTarget->width(), renderTarget->height()); |
147 bitmap.setIsOpaque(isOpaque); | 147 bitmap.setIsOpaque(isOpaque); |
148 return bitmap; | 148 return bitmap; |
149 } | 149 } |
150 | 150 |
151 SkGpuDevice* SkGpuDevice::Create(GrSurface* surface) { | 151 SkGpuDevice* SkGpuDevice::Create(GrSurface* surface) { |
152 GrAssert(NULL != surface); | 152 SkASSERT(NULL != surface); |
153 if (NULL == surface->asRenderTarget() || NULL == surface->getContext()) { | 153 if (NULL == surface->asRenderTarget() || NULL == surface->getContext()) { |
154 return NULL; | 154 return NULL; |
155 } | 155 } |
156 if (surface->asTexture()) { | 156 if (surface->asTexture()) { |
157 return SkNEW_ARGS(SkGpuDevice, (surface->getContext(), surface->asTextur
e())); | 157 return SkNEW_ARGS(SkGpuDevice, (surface->getContext(), surface->asTextur
e())); |
158 } else { | 158 } else { |
159 return SkNEW_ARGS(SkGpuDevice, (surface->getContext(), surface->asRender
Target())); | 159 return SkNEW_ARGS(SkGpuDevice, (surface->getContext(), surface->asRender
Target())); |
160 } | 160 } |
161 } | 161 } |
162 | 162 |
(...skipping 11 matching lines...) Expand all Loading... |
174 GrRenderTarget* renderTarget, | 174 GrRenderTarget* renderTarget, |
175 bool cached) { | 175 bool cached) { |
176 fDrawProcs = NULL; | 176 fDrawProcs = NULL; |
177 | 177 |
178 fContext = context; | 178 fContext = context; |
179 fContext->ref(); | 179 fContext->ref(); |
180 | 180 |
181 fRenderTarget = NULL; | 181 fRenderTarget = NULL; |
182 fNeedClear = false; | 182 fNeedClear = false; |
183 | 183 |
184 GrAssert(NULL != renderTarget); | 184 SkASSERT(NULL != renderTarget); |
185 fRenderTarget = renderTarget; | 185 fRenderTarget = renderTarget; |
186 fRenderTarget->ref(); | 186 fRenderTarget->ref(); |
187 | 187 |
188 // Hold onto to the texture in the pixel ref (if there is one) because the t
exture holds a ref | 188 // Hold onto to the texture in the pixel ref (if there is one) because the t
exture holds a ref |
189 // on the RT but not vice-versa. | 189 // on the RT but not vice-versa. |
190 // TODO: Remove this trickery once we figure out how to make SkGrPixelRef do
this without | 190 // TODO: Remove this trickery once we figure out how to make SkGrPixelRef do
this without |
191 // busting chrome (for a currently unknown reason). | 191 // busting chrome (for a currently unknown reason). |
192 GrSurface* surface = fRenderTarget->asTexture(); | 192 GrSurface* surface = fRenderTarget->asTexture(); |
193 if (NULL == surface) { | 193 if (NULL == surface) { |
194 surface = fRenderTarget; | 194 surface = fRenderTarget; |
(...skipping 28 matching lines...) Expand all Loading... |
223 desc.fHeight = height; | 223 desc.fHeight = height; |
224 desc.fConfig = SkBitmapConfig2GrPixelConfig(config); | 224 desc.fConfig = SkBitmapConfig2GrPixelConfig(config); |
225 desc.fSampleCnt = sampleCount; | 225 desc.fSampleCnt = sampleCount; |
226 | 226 |
227 SkAutoTUnref<GrTexture> texture(fContext->createUncachedTexture(desc, NULL,
0)); | 227 SkAutoTUnref<GrTexture> texture(fContext->createUncachedTexture(desc, NULL,
0)); |
228 | 228 |
229 if (NULL != texture) { | 229 if (NULL != texture) { |
230 fRenderTarget = texture->asRenderTarget(); | 230 fRenderTarget = texture->asRenderTarget(); |
231 fRenderTarget->ref(); | 231 fRenderTarget->ref(); |
232 | 232 |
233 GrAssert(NULL != fRenderTarget); | 233 SkASSERT(NULL != fRenderTarget); |
234 | 234 |
235 // wrap the bitmap with a pixelref to expose our texture | 235 // wrap the bitmap with a pixelref to expose our texture |
236 SkGrPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (texture)); | 236 SkGrPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (texture)); |
237 this->setPixelRef(pr, 0)->unref(); | 237 this->setPixelRef(pr, 0)->unref(); |
238 } else { | 238 } else { |
239 GrPrintf("--- failed to create gpu-offscreen [%d %d]\n", | 239 GrPrintf("--- failed to create gpu-offscreen [%d %d]\n", |
240 width, height); | 240 width, height); |
241 GrAssert(false); | 241 SkASSERT(false); |
242 } | 242 } |
243 } | 243 } |
244 | 244 |
245 SkGpuDevice::~SkGpuDevice() { | 245 SkGpuDevice::~SkGpuDevice() { |
246 if (fDrawProcs) { | 246 if (fDrawProcs) { |
247 delete fDrawProcs; | 247 delete fDrawProcs; |
248 } | 248 } |
249 | 249 |
250 // The GrContext takes a ref on the target. We don't want to cause the rende
r | 250 // The GrContext takes a ref on the target. We don't want to cause the rende
r |
251 // target to be unnecessarily kept alive. | 251 // target to be unnecessarily kept alive. |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
391 | 391 |
392 canvTemp.roundOut(&devTemp); | 392 canvTemp.roundOut(&devTemp); |
393 | 393 |
394 devTemp.offset(-clipData.fOrigin.fX, -clipData.fOrigin.fY); | 394 devTemp.offset(-clipData.fOrigin.fX, -clipData.fOrigin.fY); |
395 | 395 |
396 if (!devBound.intersect(devTemp)) { | 396 if (!devBound.intersect(devTemp)) { |
397 devBound.setEmpty(); | 397 devBound.setEmpty(); |
398 } | 398 } |
399 } | 399 } |
400 | 400 |
401 GrAssert(devBound.contains(clipRegion.getBounds())); | 401 SkASSERT(devBound.contains(clipRegion.getBounds())); |
402 } | 402 } |
403 #endif | 403 #endif |
404 | 404 |
405 /////////////////////////////////////////////////////////////////////////////// | 405 /////////////////////////////////////////////////////////////////////////////// |
406 | 406 |
407 // call this every draw call, to ensure that the context reflects our state, | 407 // call this every draw call, to ensure that the context reflects our state, |
408 // and not the state from some other canvas/device | 408 // and not the state from some other canvas/device |
409 void SkGpuDevice::prepareDraw(const SkDraw& draw, bool forceIdentity) { | 409 void SkGpuDevice::prepareDraw(const SkDraw& draw, bool forceIdentity) { |
410 GrAssert(NULL != fClipData.fClipStack); | 410 SkASSERT(NULL != fClipData.fClipStack); |
411 | 411 |
412 fContext->setRenderTarget(fRenderTarget); | 412 fContext->setRenderTarget(fRenderTarget); |
413 | 413 |
414 SkASSERT(draw.fClipStack && draw.fClipStack == fClipData.fClipStack); | 414 SkASSERT(draw.fClipStack && draw.fClipStack == fClipData.fClipStack); |
415 | 415 |
416 if (forceIdentity) { | 416 if (forceIdentity) { |
417 fContext->setIdentityMatrix(); | 417 fContext->setIdentityMatrix(); |
418 } else { | 418 } else { |
419 fContext->setMatrix(*draw.fMatrix); | 419 fContext->setMatrix(*draw.fMatrix); |
420 } | 420 } |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
485 dm = SkXfermode::kISA_Coeff; | 485 dm = SkXfermode::kISA_Coeff; |
486 #endif | 486 #endif |
487 } | 487 } |
488 grPaint->setBlendFunc(sk_blend_to_grblend(sm), sk_blend_to_grblend(dm)); | 488 grPaint->setBlendFunc(sk_blend_to_grblend(sm), sk_blend_to_grblend(dm)); |
489 | 489 |
490 if (justAlpha) { | 490 if (justAlpha) { |
491 uint8_t alpha = skPaint.getAlpha(); | 491 uint8_t alpha = skPaint.getAlpha(); |
492 grPaint->setColor(GrColorPackRGBA(alpha, alpha, alpha, alpha)); | 492 grPaint->setColor(GrColorPackRGBA(alpha, alpha, alpha, alpha)); |
493 // justAlpha is currently set to true only if there is a texture, | 493 // justAlpha is currently set to true only if there is a texture, |
494 // so constantColor should not also be true. | 494 // so constantColor should not also be true. |
495 GrAssert(!constantColor); | 495 SkASSERT(!constantColor); |
496 } else { | 496 } else { |
497 grPaint->setColor(SkColor2GrColor(skPaint.getColor())); | 497 grPaint->setColor(SkColor2GrColor(skPaint.getColor())); |
498 } | 498 } |
499 | 499 |
500 SkColorFilter* colorFilter = skPaint.getColorFilter(); | 500 SkColorFilter* colorFilter = skPaint.getColorFilter(); |
501 if (NULL != colorFilter) { | 501 if (NULL != colorFilter) { |
502 // if the source color is a constant then apply the filter here once rat
her than per pixel | 502 // if the source color is a constant then apply the filter here once rat
her than per pixel |
503 // in a shader. | 503 // in a shader. |
504 if (constantColor) { | 504 if (constantColor) { |
505 SkColor filtered = colorFilter->filterColor(skPaint.getColor()); | 505 SkColor filtered = colorFilter->filterColor(skPaint.getColor()); |
(...skipping 749 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1255 return true; | 1255 return true; |
1256 } | 1256 } |
1257 return false; | 1257 return false; |
1258 } | 1258 } |
1259 | 1259 |
1260 static bool may_color_bleed(const SkRect& srcRect, | 1260 static bool may_color_bleed(const SkRect& srcRect, |
1261 const SkRect& transformedRect, | 1261 const SkRect& transformedRect, |
1262 const SkMatrix& m) { | 1262 const SkMatrix& m) { |
1263 // Only gets called if has_aligned_samples returned false. | 1263 // Only gets called if has_aligned_samples returned false. |
1264 // So we can assume that sampling is axis aligned but not texel aligned. | 1264 // So we can assume that sampling is axis aligned but not texel aligned. |
1265 GrAssert(!has_aligned_samples(srcRect, transformedRect)); | 1265 SkASSERT(!has_aligned_samples(srcRect, transformedRect)); |
1266 SkRect innerSrcRect(srcRect), innerTransformedRect, | 1266 SkRect innerSrcRect(srcRect), innerTransformedRect, |
1267 outerTransformedRect(transformedRect); | 1267 outerTransformedRect(transformedRect); |
1268 innerSrcRect.inset(SK_ScalarHalf, SK_ScalarHalf); | 1268 innerSrcRect.inset(SK_ScalarHalf, SK_ScalarHalf); |
1269 m.mapRect(&innerTransformedRect, innerSrcRect); | 1269 m.mapRect(&innerTransformedRect, innerSrcRect); |
1270 | 1270 |
1271 // The gap between outerTransformedRect and innerTransformedRect | 1271 // The gap between outerTransformedRect and innerTransformedRect |
1272 // represents the projection of the source border area, which is | 1272 // represents the projection of the source border area, which is |
1273 // problematic for color bleeding. We must check whether any | 1273 // problematic for color bleeding. We must check whether any |
1274 // destination pixels sample the border area. | 1274 // destination pixels sample the border area. |
1275 outerTransformedRect.inset(COLOR_BLEED_TOLERANCE, COLOR_BLEED_TOLERANCE); | 1275 outerTransformedRect.inset(COLOR_BLEED_TOLERANCE, COLOR_BLEED_TOLERANCE); |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1375 return; | 1375 return; |
1376 } | 1376 } |
1377 | 1377 |
1378 fContext->drawRectToRect(grPaint, dstRect, paintRect, &m); | 1378 fContext->drawRectToRect(grPaint, dstRect, paintRect, &m); |
1379 } | 1379 } |
1380 | 1380 |
1381 static bool filter_texture(SkDevice* device, GrContext* context, | 1381 static bool filter_texture(SkDevice* device, GrContext* context, |
1382 GrTexture* texture, SkImageFilter* filter, | 1382 GrTexture* texture, SkImageFilter* filter, |
1383 int w, int h, const SkMatrix& ctm, SkBitmap* result, | 1383 int w, int h, const SkMatrix& ctm, SkBitmap* result, |
1384 SkIPoint* offset) { | 1384 SkIPoint* offset) { |
1385 GrAssert(filter); | 1385 SkASSERT(filter); |
1386 SkDeviceImageFilterProxy proxy(device); | 1386 SkDeviceImageFilterProxy proxy(device); |
1387 | 1387 |
1388 if (filter->canFilterImageGPU()) { | 1388 if (filter->canFilterImageGPU()) { |
1389 // Save the render target and set it to NULL, so we don't accidentally d
raw to it in the | 1389 // Save the render target and set it to NULL, so we don't accidentally d
raw to it in the |
1390 // filter. Also set the clip wide open and the matrix to identity. | 1390 // filter. Also set the clip wide open and the matrix to identity. |
1391 GrContext::AutoWideOpenIdentityDraw awo(context, NULL); | 1391 GrContext::AutoWideOpenIdentityDraw awo(context, NULL); |
1392 return filter->filterImageGPU(&proxy, wrap_texture(texture), ctm, result
, offset); | 1392 return filter->filterImageGPU(&proxy, wrap_texture(texture), ctm, result
, offset); |
1393 } else { | 1393 } else { |
1394 return false; | 1394 return false; |
1395 } | 1395 } |
(...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1791 GrPrintf("---- failed to create compatible device texture [%d %d]\n", wi
dth, height); | 1791 GrPrintf("---- failed to create compatible device texture [%d %d]\n", wi
dth, height); |
1792 return NULL; | 1792 return NULL; |
1793 } | 1793 } |
1794 } | 1794 } |
1795 | 1795 |
1796 SkGpuDevice::SkGpuDevice(GrContext* context, | 1796 SkGpuDevice::SkGpuDevice(GrContext* context, |
1797 GrTexture* texture, | 1797 GrTexture* texture, |
1798 bool needClear) | 1798 bool needClear) |
1799 : SkDevice(make_bitmap(context, texture->asRenderTarget())) { | 1799 : SkDevice(make_bitmap(context, texture->asRenderTarget())) { |
1800 | 1800 |
1801 GrAssert(texture && texture->asRenderTarget()); | 1801 SkASSERT(texture && texture->asRenderTarget()); |
1802 // This constructor is called from onCreateCompatibleDevice. It has locked t
he RT in the texture | 1802 // This constructor is called from onCreateCompatibleDevice. It has locked t
he RT in the texture |
1803 // cache. We pass true for the third argument so that it will get unlocked. | 1803 // cache. We pass true for the third argument so that it will get unlocked. |
1804 this->initFromRenderTarget(context, texture->asRenderTarget(), true); | 1804 this->initFromRenderTarget(context, texture->asRenderTarget(), true); |
1805 fNeedClear = needClear; | 1805 fNeedClear = needClear; |
1806 } | 1806 } |
OLD | NEW |