| 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 |