Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 | |
| 2 /* | 1 /* |
| 3 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
| 4 * | 3 * |
| 5 * 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 |
| 6 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 7 */ | 6 */ |
| 8 | 7 |
| 9 #include "GrContext.h" | 8 #include "GrContext.h" |
| 10 #include "GrContextOptions.h" | 9 #include "GrContextOptions.h" |
| 11 #include "GrDrawingManager.h" | 10 #include "GrDrawingManager.h" |
| 12 #include "GrDrawContext.h" | 11 #include "GrDrawContext.h" |
| 13 #include "GrLayerCache.h" | 12 #include "GrLayerCache.h" |
| 14 #include "GrResourceCache.h" | 13 #include "GrResourceCache.h" |
| 15 #include "GrResourceProvider.h" | 14 #include "GrResourceProvider.h" |
| 16 #include "GrSoftwarePathRenderer.h" | 15 #include "GrSoftwarePathRenderer.h" |
| 17 #include "GrSurfacePriv.h" | 16 #include "GrSurfacePriv.h" |
| 18 #include "GrTextBlobCache.h" | 17 #include "GrTextBlobCache.h" |
| 19 | 18 |
| 20 #include "SkConfig8888.h" | 19 #include "SkConfig8888.h" |
| 21 #include "SkGrPriv.h" | 20 #include "SkGrPriv.h" |
| 21 #include "SkTypes.h" | |
| 22 | 22 |
| 23 #include "effects/GrConfigConversionEffect.h" | 23 #include "effects/GrConfigConversionEffect.h" |
| 24 | 24 |
| 25 #define ASSERT_OWNED_RESOURCE(R) SkASSERT(!(R) || (R)->getContext() == this) | 25 #define ASSERT_OWNED_RESOURCE(R) SkASSERT(!(R) || (R)->getContext() == this) |
| 26 #define RETURN_IF_ABANDONED if (fDrawingManager->abandoned()) { return; } | 26 #define RETURN_IF_ABANDONED if (fDrawingManager->abandoned()) { return; } |
| 27 #define RETURN_FALSE_IF_ABANDONED if (fDrawingManager->abandoned()) { return fal se; } | 27 #define RETURN_FALSE_IF_ABANDONED if (fDrawingManager->abandoned()) { return fal se; } |
| 28 #define RETURN_NULL_IF_ABANDONED if (fDrawingManager->abandoned()) { return null ptr; } | 28 #define RETURN_NULL_IF_ABANDONED if (fDrawingManager->abandoned()) { return null ptr; } |
| 29 | 29 |
| 30 //////////////////////////////////////////////////////////////////////////////// | 30 //////////////////////////////////////////////////////////////////////////////// |
| 31 | 31 |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 217 dstPI.fColorType = srcPI.fColorType; | 217 dstPI.fColorType = srcPI.fColorType; |
| 218 dstPI.fAlphaType = kPremul_SkAlphaType; | 218 dstPI.fAlphaType = kPremul_SkAlphaType; |
| 219 dstPI.fPixels = outPixels; | 219 dstPI.fPixels = outPixels; |
| 220 dstPI.fRowBytes = outRowBytes; | 220 dstPI.fRowBytes = outRowBytes; |
| 221 | 221 |
| 222 return srcPI.convertPixelsTo(&dstPI, width, height); | 222 return srcPI.convertPixelsTo(&dstPI, width, height); |
| 223 } | 223 } |
| 224 | 224 |
| 225 bool GrContext::writeSurfacePixels(GrSurface* surface, | 225 bool GrContext::writeSurfacePixels(GrSurface* surface, |
| 226 int left, int top, int width, int height, | 226 int left, int top, int width, int height, |
| 227 GrPixelConfig srcConfig, const void* buffer, size_t rowBytes, | 227 GrPixelConfig srcConfig, const SkTArray<SkMip MapLevel>& texels, |
| 228 uint32_t pixelOpsFlags) { | 228 uint32_t pixelOpsFlags) { |
| 229 RETURN_FALSE_IF_ABANDONED | 229 RETURN_FALSE_IF_ABANDONED |
| 230 ASSERT_OWNED_RESOURCE(surface); | 230 ASSERT_OWNED_RESOURCE(surface); |
| 231 SkASSERT(surface); | 231 SkASSERT(surface); |
| 232 | 232 |
| 233 SkTArray<SkMipMapLevel> texelsCopy(texels); | |
| 234 | |
| 233 this->testPMConversionsIfNecessary(pixelOpsFlags); | 235 this->testPMConversionsIfNecessary(pixelOpsFlags); |
| 234 | 236 |
| 235 // Trim the params here so that if we wind up making a temporary surface it can be as small as | 237 // Trim the params here so that if we wind up making a temporary surface it can be as small as |
| 236 // necessary and because GrGpu::getWritePixelsInfo requires it. | 238 // necessary and because GrGpu::getWritePixelsInfo requires it. |
| 237 if (!GrSurfacePriv::AdjustWritePixelParams(surface->width(), surface->height (), | 239 for (int currentMipLevel = texelsCopy.count() - 1; currentMipLevel >= 0; cur rentMipLevel--) { |
| 238 GrBytesPerPixel(srcConfig), &left , &top, &width, | 240 // make sure the texelmap's size range is within int range |
| 239 &height, &buffer, &rowBytes)) { | 241 if (texelsCopy[currentMipLevel].fWidth > SK_MaxS32 |
| 240 return false; | 242 || texelsCopy[currentMipLevel].fHeight > SK_MaxS32) { |
|
bsalomon
2015/10/28 16:40:44
|| on prev line
Does SkMipMapLevel need to use ui
cblume
2015/10/28 22:49:40
Okay, I'll make them ints and remove the range che
| |
| 243 return false; | |
| 244 } | |
| 245 int currentMipWidth = texelsCopy[currentMipLevel].fWidth; | |
| 246 int currentMipHeight = texelsCopy[currentMipLevel].fHeight; | |
| 247 | |
| 248 SkMipMapLevel& currentMipMap = texelsCopy[currentMipLevel]; | |
| 249 if (!GrSurfacePriv::AdjustWritePixelParams(surface->width(), surface->he ight(), | |
| 250 GrBytesPerPixel(srcConfig), & left, &top, | |
| 251 ¤tMipWidth, ¤tMip Height, | |
| 252 ¤tMipMap.fTexels, | |
| 253 ¤tMipMap.fRowBytes)) { | |
| 254 return false; | |
| 255 } | |
| 256 | |
| 257 // make sure the size range is within the texelmap's size range | |
| 258 if (currentMipWidth < 0 || currentMipHeight < 0) { | |
| 259 return false; | |
| 260 } | |
| 261 texelsCopy[currentMipLevel].fWidth = currentMipWidth; | |
| 262 texelsCopy[currentMipLevel].fHeight = currentMipHeight; | |
| 241 } | 263 } |
| 242 | 264 |
| 243 bool applyPremulToSrc = false; | 265 bool applyPremulToSrc = false; |
| 244 if (kUnpremul_PixelOpsFlag & pixelOpsFlags) { | 266 if (kUnpremul_PixelOpsFlag & pixelOpsFlags) { |
| 245 if (!GrPixelConfigIs8888(srcConfig)) { | 267 if (!GrPixelConfigIs8888(srcConfig)) { |
| 246 return false; | 268 return false; |
| 247 } | 269 } |
| 248 applyPremulToSrc = true; | 270 applyPremulToSrc = true; |
| 249 } | 271 } |
| 250 | 272 |
| 251 GrGpu::DrawPreference drawPreference = GrGpu::kNoDraw_DrawPreference; | 273 GrGpu::DrawPreference drawPreference = GrGpu::kNoDraw_DrawPreference; |
| 252 // Don't prefer to draw for the conversion (and thereby access a texture fro m the cache) when | 274 // Don't prefer to draw for the conversion (and thereby access a texture fro m the cache) when |
| 253 // we've already determined that there isn't a roundtrip preserving conversi on processor pair. | 275 // we've already determined that there isn't a roundtrip preserving conversi on processor pair. |
| 254 if (applyPremulToSrc && !this->didFailPMUPMConversionTest()) { | 276 if (applyPremulToSrc && !this->didFailPMUPMConversionTest()) { |
| 255 drawPreference = GrGpu::kCallerPrefersDraw_DrawPreference; | 277 drawPreference = GrGpu::kCallerPrefersDraw_DrawPreference; |
| 256 } | 278 } |
| 257 | 279 |
| 258 GrGpu::WritePixelTempDrawInfo tempDrawInfo; | 280 GrGpu::WritePixelTempDrawInfo tempDrawInfo; |
| 259 if (!fGpu->getWritePixelsInfo(surface, width, height, rowBytes, srcConfig, & drawPreference, | 281 if (!fGpu->getWritePixelsInfo(surface, width, height, srcConfig, &drawPrefer ence, |
| 260 &tempDrawInfo)) { | 282 &tempDrawInfo)) { |
| 261 return false; | 283 return false; |
| 262 } | 284 } |
| 263 | 285 |
| 264 if (!(kDontFlush_PixelOpsFlag & pixelOpsFlags) && surface->surfacePriv().has PendingIO()) { | 286 if (!(kDontFlush_PixelOpsFlag & pixelOpsFlags) && surface->surfacePriv().has PendingIO()) { |
| 265 this->flush(); | 287 this->flush(); |
| 266 } | 288 } |
| 267 | 289 |
| 268 SkAutoTUnref<GrTexture> tempTexture; | 290 SkAutoTUnref<GrTexture> tempTexture; |
| 269 if (GrGpu::kNoDraw_DrawPreference != drawPreference) { | 291 if (GrGpu::kNoDraw_DrawPreference != drawPreference) { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 305 if (!fp) { | 327 if (!fp) { |
| 306 return false; | 328 return false; |
| 307 } | 329 } |
| 308 } | 330 } |
| 309 GrRenderTarget* renderTarget = surface->asRenderTarget(); | 331 GrRenderTarget* renderTarget = surface->asRenderTarget(); |
| 310 SkASSERT(renderTarget); | 332 SkASSERT(renderTarget); |
| 311 if (tempTexture->surfacePriv().hasPendingIO()) { | 333 if (tempTexture->surfacePriv().hasPendingIO()) { |
| 312 this->flush(); | 334 this->flush(); |
| 313 } | 335 } |
| 314 if (applyPremulToSrc) { | 336 if (applyPremulToSrc) { |
| 315 size_t tmpRowBytes = 4 * width; | 337 for (int currentMipLevel = texelsCopy.count() - 1; currentMipLev el >= 0; |
| 316 tmpPixels.reset(width * height); | 338 currentMipLevel--) { |
| 317 if (!sw_convert_to_premul(srcConfig, width, height, rowBytes, bu ffer, tmpRowBytes, | 339 SkMipMapLevel& currentMipMap = texelsCopy[currentMipLevel]; |
| 318 tmpPixels.get())) { | 340 int currentWidth = currentMipMap.fWidth; |
| 319 return false; | 341 int currentHeight = currentMipMap.fHeight; |
| 342 size_t tmpRowBytes = 4 * currentWidth; | |
| 343 tmpPixels.reset(currentWidth * currentHeight); | |
| 344 if (!sw_convert_to_premul(srcConfig, currentWidth, currentHe ight, | |
| 345 currentMipMap.fRowBytes, | |
| 346 currentMipMap.fTexels, tmpRowBytes , | |
| 347 tmpPixels.get())) { | |
| 348 return false; | |
| 349 } | |
| 350 currentMipMap.fRowBytes = tmpRowBytes; | |
| 351 currentMipMap.fTexels = tmpPixels.get(); | |
| 320 } | 352 } |
| 321 rowBytes = tmpRowBytes; | |
| 322 buffer = tmpPixels.get(); | |
| 323 applyPremulToSrc = false; | 353 applyPremulToSrc = false; |
| 324 } | 354 } |
| 325 if (!fGpu->writePixels(tempTexture, 0, 0, width, height, | 355 if (!fGpu->writePixels(tempTexture, 0, 0, width, height, |
| 326 tempDrawInfo.fTempSurfaceDesc.fConfig, buffer , | 356 tempDrawInfo.fTempSurfaceDesc.fConfig, texels Copy)) { |
| 327 rowBytes)) { | |
| 328 return false; | 357 return false; |
| 329 } | 358 } |
| 330 SkMatrix matrix; | 359 SkMatrix matrix; |
| 331 matrix.setTranslate(SkIntToScalar(left), SkIntToScalar(top)); | 360 matrix.setTranslate(SkIntToScalar(left), SkIntToScalar(top)); |
| 332 SkAutoTUnref<GrDrawContext> drawContext(this->drawContext(renderTarg et)); | 361 SkAutoTUnref<GrDrawContext> drawContext(this->drawContext(renderTarg et)); |
| 333 if (!drawContext) { | 362 if (!drawContext) { |
| 334 return false; | 363 return false; |
| 335 } | 364 } |
| 336 paint.addColorFragmentProcessor(fp); | 365 paint.addColorFragmentProcessor(fp); |
| 337 SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(hei ght)); | 366 SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(hei ght)); |
| 338 drawContext->drawRect(GrClip::WideOpen(), paint, matrix, rect, nullp tr); | 367 drawContext->drawRect(GrClip::WideOpen(), paint, matrix, rect, nullp tr); |
|
bsalomon
2015/10/28 16:40:44
Seems like we will populate a mip chain on the tem
cblume
2015/10/28 22:49:40
You are correct. In this case, it populates the mi
| |
| 339 | 368 |
| 340 if (kFlushWrites_PixelOp & pixelOpsFlags) { | 369 if (kFlushWrites_PixelOp & pixelOpsFlags) { |
| 341 this->flushSurfaceWrites(surface); | 370 this->flushSurfaceWrites(surface); |
| 342 } | 371 } |
| 343 } | 372 } |
| 344 } | 373 } |
| 345 if (!tempTexture) { | 374 if (!tempTexture) { |
| 346 if (applyPremulToSrc) { | 375 if (applyPremulToSrc) { |
| 347 size_t tmpRowBytes = 4 * width; | 376 for (int currentMipLevel = texelsCopy.count() - 1; currentMipLevel > = 0; |
| 348 tmpPixels.reset(width * height); | 377 currentMipLevel--) { |
| 349 if (!sw_convert_to_premul(srcConfig, width, height, rowBytes, buffer , tmpRowBytes, | 378 SkMipMapLevel& currentMipMap = texelsCopy[currentMipLevel]; |
| 350 tmpPixels.get())) { | 379 int currentMipWidth = currentMipMap.fWidth; |
| 351 return false; | 380 int currentMipHeight = currentMipMap.fHeight; |
| 381 size_t tmpRowBytes = 4 * currentMipWidth; | |
| 382 tmpPixels.reset(currentMipWidth * currentMipHeight); | |
| 383 if (!sw_convert_to_premul(srcConfig, currentMipWidth, currentMip Height, | |
| 384 currentMipMap.fRowBytes, currentMipMap .fTexels, | |
| 385 tmpRowBytes, tmpPixels.get())) { | |
| 386 return false; | |
| 387 } | |
| 388 currentMipMap.fRowBytes = tmpRowBytes; | |
| 389 currentMipMap.fTexels = tmpPixels.get(); | |
| 352 } | 390 } |
| 353 rowBytes = tmpRowBytes; | |
| 354 buffer = tmpPixels.get(); | |
| 355 applyPremulToSrc = false; | 391 applyPremulToSrc = false; |
| 356 } | 392 } |
| 357 return fGpu->writePixels(surface, left, top, width, height, srcConfig, b uffer, rowBytes); | 393 return fGpu->writePixels(surface, left, top, width, height, srcConfig, t exelsCopy); |
| 358 } | 394 } |
| 359 return true; | 395 return true; |
| 360 } | 396 } |
| 361 | 397 |
| 398 bool GrContext::writeSurfacePixels(GrSurface* surface, | |
| 399 int left, int top, int width, int height, | |
| 400 GrPixelConfig srcConfig, const void* buffer, size_t rowBytes, | |
| 401 uint32_t pixelOpsFlags) { | |
| 402 if (width <= 0 || height <= 0) { | |
| 403 return false; | |
| 404 } | |
| 405 const uint32_t baseLevelWidth = width; | |
| 406 const uint32_t baseLevelHeight = height; | |
| 407 | |
| 408 SkMipMapLevel level(buffer, rowBytes, baseLevelWidth, baseLevelHeight); | |
| 409 const int mipLevelCount = 1; | |
| 410 SkTArray<SkMipMapLevel> texels(mipLevelCount); | |
| 411 texels.push_back(level); | |
| 412 | |
| 413 return this->writeSurfacePixels(surface, left, top, width, height, srcConfig , texels, | |
| 414 pixelOpsFlags); | |
| 415 } | |
| 416 | |
| 362 bool GrContext::readSurfacePixels(GrSurface* src, | 417 bool GrContext::readSurfacePixels(GrSurface* src, |
| 363 int left, int top, int width, int height, | 418 int left, int top, int width, int height, |
| 364 GrPixelConfig dstConfig, void* buffer, size_t rowBytes, | 419 GrPixelConfig dstConfig, void* buffer, size_t rowBytes, |
| 365 uint32_t flags) { | 420 uint32_t flags) { |
| 366 RETURN_FALSE_IF_ABANDONED | 421 RETURN_FALSE_IF_ABANDONED |
| 367 ASSERT_OWNED_RESOURCE(src); | 422 ASSERT_OWNED_RESOURCE(src); |
| 368 SkASSERT(src); | 423 SkASSERT(src); |
| 369 | 424 |
| 370 this->testPMConversionsIfNecessary(flags); | 425 this->testPMConversionsIfNecessary(flags); |
| 371 SkAutoMutexAcquire ama(fReadPixelsMutex); | 426 SkAutoMutexAcquire ama(fReadPixelsMutex); |
| (...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 666 | 721 |
| 667 void GrContext::setResourceCacheLimits(int maxTextures, size_t maxTextureBytes) { | 722 void GrContext::setResourceCacheLimits(int maxTextures, size_t maxTextureBytes) { |
| 668 fResourceCache->setLimits(maxTextures, maxTextureBytes); | 723 fResourceCache->setLimits(maxTextures, maxTextureBytes); |
| 669 } | 724 } |
| 670 | 725 |
| 671 ////////////////////////////////////////////////////////////////////////////// | 726 ////////////////////////////////////////////////////////////////////////////// |
| 672 | 727 |
| 673 void GrContext::dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const { | 728 void GrContext::dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const { |
| 674 fResourceCache->dumpMemoryStatistics(traceMemoryDump); | 729 fResourceCache->dumpMemoryStatistics(traceMemoryDump); |
| 675 } | 730 } |
| OLD | NEW |