OLD | NEW |
---|---|
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 #include "GrContext.h" | 9 #include "GrContext.h" |
10 | 10 |
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
322 dstPI.fRowBytes = outRowBytes; | 322 dstPI.fRowBytes = outRowBytes; |
323 | 323 |
324 return srcPI.convertPixelsTo(&dstPI, width, height); | 324 return srcPI.convertPixelsTo(&dstPI, width, height); |
325 } | 325 } |
326 | 326 |
327 bool GrContext::writeSurfacePixels(GrSurface* surface, | 327 bool GrContext::writeSurfacePixels(GrSurface* surface, |
328 int left, int top, int width, int height, | 328 int left, int top, int width, int height, |
329 GrPixelConfig srcConfig, const void* buffer, size_t rowBytes, | 329 GrPixelConfig srcConfig, const void* buffer, size_t rowBytes, |
330 uint32_t pixelOpsFlags) { | 330 uint32_t pixelOpsFlags) { |
331 RETURN_FALSE_IF_ABANDONED | 331 RETURN_FALSE_IF_ABANDONED |
332 { | |
333 GrTexture* texture = NULL; | |
334 if (!(kUnpremul_PixelOpsFlag & pixelOpsFlags) && (texture = surface->asT exture()) && | |
335 fGpu->canWriteTexturePixels(texture, srcConfig) && | |
336 (!fCaps->useDrawInsteadOfPartialRenderTargetWrite() || !surface->asR enderTarget() || | |
337 (width == texture->width() && height == texture->height()))) { | |
338 | |
339 if (!(kDontFlush_PixelOpsFlag & pixelOpsFlags) && | |
340 surface->surfacePriv().hasPendingIO()) { | |
341 this->flush(); | |
342 } | |
343 return fGpu->writeTexturePixels(texture, left, top, width, height, | |
344 srcConfig, buffer, rowBytes); | |
345 // Don't need to check kFlushWrites_PixelOp here, we just did a dire ct write so the | |
346 // upload is already flushed. | |
347 } | |
348 } | |
349 | 332 |
350 // Trim the params here so that if we wind up making a temporary surface it can be as small as | 333 // Trim the params here so that if we wind up making a temporary surface it can be as small as |
351 // necessary. | 334 // necessary and because GrGpu::getWritePixelsInfo requires it. |
352 if (!GrSurfacePriv::AdjustWritePixelParams(surface->width(), surface->height (), | 335 if (!GrSurfacePriv::AdjustWritePixelParams(surface->width(), surface->height (), |
353 GrBytesPerPixel(srcConfig), &left , &top, &width, | 336 GrBytesPerPixel(srcConfig), &left , &top, &width, |
354 &height, &buffer, &rowBytes)) { | 337 &height, &buffer, &rowBytes)) { |
355 return false; | 338 return false; |
356 } | 339 } |
357 | 340 |
robertphillips
2015/07/28 13:15:23
premul -> performUPMToPMConversion ?
bsalomon
2015/07/28 14:58:17
Done, but somewhat shorter rename
| |
358 // If we didn't do a direct texture write then we upload the pixels to a tex ture and draw. | 341 bool premul = false; |
359 GrRenderTarget* renderTarget = surface->asRenderTarget(); | |
360 if (!renderTarget) { | |
361 return false; | |
362 } | |
363 | |
364 // We ignore the preferred config unless it is a R/B swap of the src config. In that case | |
365 // we will upload the original src data to a scratch texture but we will spo of it as the swapped | |
366 // config. This scratch will then have R and B swapped. We correct for this by swapping again | |
367 // when drawing the scratch to the dst using a conversion effect. | |
368 bool swapRAndB = false; | |
369 GrPixelConfig writeConfig = srcConfig; | |
370 if (GrPixelConfigSwapRAndB(srcConfig) == | |
371 fGpu->preferredWritePixelsConfig(srcConfig, renderTarget->config())) { | |
372 writeConfig = GrPixelConfigSwapRAndB(srcConfig); | |
373 swapRAndB = true; | |
374 } | |
375 | |
376 GrSurfaceDesc desc; | |
377 desc.fWidth = width; | |
378 desc.fHeight = height; | |
379 desc.fConfig = writeConfig; | |
380 SkAutoTUnref<GrTexture> texture(this->textureProvider()->refScratchTexture(d esc, | |
381 GrTextureProvider::kApprox_ScratchTexMatch)); | |
382 if (!texture) { | |
383 return false; | |
384 } | |
385 | |
386 SkAutoTUnref<const GrFragmentProcessor> fp; | |
387 SkMatrix textureMatrix; | |
388 textureMatrix.setIDiv(texture->width(), texture->height()); | |
389 | |
390 // allocate a tmp buffer and sw convert the pixels to premul | |
391 SkAutoSTMalloc<128 * 128, uint32_t> tmpPixels(0); | |
392 | |
393 GrPaint paint; | |
394 if (kUnpremul_PixelOpsFlag & pixelOpsFlags) { | 342 if (kUnpremul_PixelOpsFlag & pixelOpsFlags) { |
395 if (!GrPixelConfigIs8888(srcConfig)) { | 343 if (!GrPixelConfigIs8888(srcConfig)) { |
robertphillips
2015/07/28 13:15:22
// Our UPMToPM conversion only works on 8888. ?
W
bsalomon
2015/07/28 14:58:17
565 has no alpha :)
It would work with 4444 but i
| |
396 return false; | 344 return false; |
397 } | 345 } |
398 fp.reset(this->createUPMToPMEffect(paint.getProcessorDataManager(), text ure, swapRAndB, | 346 premul = true; |
399 textureMatrix)); | 347 } |
400 // handle the unpremul step on the CPU if we couldn't create an effect t o do it. | 348 GrGpu::DrawPreference drawPreference = premul ? GrGpu::kCallerPrefersDraw_Dr awPreference : |
401 if (!fp) { | 349 GrGpu::kNoDraw_DrawPreferenc e; |
350 GrGpu::WritePixelTempDrawInfo tempDrawInfo; | |
351 if (!fGpu->getWritePixelsInfo(surface, width, height, rowBytes, srcConfig, & drawPreference, | |
352 &tempDrawInfo)) { | |
353 return false; | |
354 } | |
355 | |
356 if (!(kDontFlush_PixelOpsFlag & pixelOpsFlags) && surface->surfacePriv().has PendingIO()) { | |
357 this->flush(); | |
358 } | |
359 | |
360 SkAutoTUnref<GrTexture> tempTexture; | |
361 if (GrGpu::kNoDraw_DrawPreference != drawPreference) { | |
362 tempTexture.reset(this->textureProvider()->refScratchTexture( | |
363 tempDrawInfo.fTempSurfaceDesc, GrTextureProvider::kApprox_ScratchTex Match)); | |
364 if (!tempTexture && GrGpu::kRequireDraw_DrawPreference == drawPreference ) { | |
365 return false; | |
366 } | |
367 } | |
368 | |
369 if (tempTexture) { | |
370 SkAutoTUnref<const GrFragmentProcessor> fp; | |
371 SkMatrix textureMatrix; | |
372 textureMatrix.setIDiv(tempTexture->width(), tempTexture->height()); | |
373 GrPaint paint; | |
374 if (premul) { | |
375 fp.reset(this->createUPMToPMEffect(paint.getProcessorDataManager(), tempTexture, | |
376 tempDrawInfo.fSwapRAndB, textureM atrix)); | |
377 // If premultiplying was the only reason for the draw, fall back to a straight write. | |
378 if (!fp && GrGpu::kCallerPrefersDraw_DrawPreference == drawPreferenc e) { | |
379 tempTexture.reset(NULL); | |
380 } | |
381 } | |
382 if (tempTexture) { | |
383 if (!fp) { | |
384 fp.reset(GrConfigConversionEffect::Create( | |
385 paint.getProcessorDataManager(), tempTexture, tempDrawInfo.f SwapRAndB, | |
386 GrConfigConversionEffect::kNone_PMConversion, textureMatrix) ); | |
387 if (!fp) { | |
388 return false; | |
389 } | |
390 } | |
391 GrRenderTarget* renderTarget = surface->asRenderTarget(); | |
392 SkASSERT(renderTarget); | |
393 if (tempTexture->surfacePriv().hasPendingIO()) { | |
394 this->flush(); | |
395 } | |
396 if (!fGpu->writeTexturePixels(tempTexture, 0, 0, width, height, | |
397 tempDrawInfo.fTempSurfaceDesc.fConfig, buffer, | |
398 rowBytes)) { | |
399 return false; | |
400 } | |
401 SkMatrix matrix; | |
402 matrix.setTranslate(SkIntToScalar(left), SkIntToScalar(top)); | |
403 GrDrawContext* drawContext = this->drawContext(); | |
404 if (!drawContext) { | |
405 return false; | |
406 } | |
407 paint.addColorProcessor(fp); | |
408 SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(hei ght)); | |
409 drawContext->drawRect(renderTarget, GrClip::WideOpen(), paint, matri x, rect, NULL); | |
410 | |
411 if (kFlushWrites_PixelOp & pixelOpsFlags) { | |
412 this->flushSurfaceWrites(surface); | |
413 } | |
414 } | |
415 } | |
416 if (!tempTexture) { | |
417 SkASSERT(surface->asTexture()); | |
418 // allocate a tmp buffer and sw convert the pixels to premul | |
419 SkAutoSTMalloc<128 * 128, uint32_t> tmpPixels(0); | |
420 if (premul) { | |
402 size_t tmpRowBytes = 4 * width; | 421 size_t tmpRowBytes = 4 * width; |
403 tmpPixels.reset(width * height); | 422 tmpPixels.reset(width * height); |
404 if (!sw_convert_to_premul(srcConfig, width, height, rowBytes, buffer , tmpRowBytes, | 423 if (!sw_convert_to_premul(srcConfig, width, height, rowBytes, buffer , tmpRowBytes, |
405 tmpPixels.get())) { | 424 tmpPixels.get())) { |
406 return false; | 425 return false; |
407 } | 426 } |
408 rowBytes = tmpRowBytes; | 427 rowBytes = tmpRowBytes; |
409 buffer = tmpPixels.get(); | 428 buffer = tmpPixels.get(); |
410 } | 429 } |
430 return fGpu->writeTexturePixels(surface->asTexture(), left, top, width, height, srcConfig, | |
431 buffer, rowBytes); | |
411 } | 432 } |
412 | |
413 if (!fp) { | |
414 fp.reset(GrConfigConversionEffect::Create(paint.getProcessorDataManager( ), | |
415 texture, | |
416 swapRAndB, | |
417 GrConfigConversionEffect::kNon e_PMConversion, | |
418 textureMatrix)); | |
419 } | |
420 | |
421 // Even if the client told us not to flush, we still flush here. The client may have known that | |
422 // writes to the original surface caused no data hazards, but they can't kno w that the scratch | |
423 // we just got is safe. | |
424 if (texture->surfacePriv().hasPendingIO()) { | |
425 this->flush(); | |
426 } | |
427 if (!fGpu->writeTexturePixels(texture, 0, 0, width, height, | |
428 writeConfig, buffer, rowBytes)) { | |
429 return false; | |
430 } | |
431 | |
432 SkMatrix matrix; | |
433 matrix.setTranslate(SkIntToScalar(left), SkIntToScalar(top)); | |
434 | |
435 GrDrawContext* drawContext = this->drawContext(); | |
436 if (!drawContext) { | |
437 return false; | |
438 } | |
439 | |
440 paint.addColorProcessor(fp); | |
441 | |
442 SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height)); | |
443 | |
444 drawContext->drawRect(renderTarget, GrClip::WideOpen(), paint, matrix, rect, NULL); | |
445 | |
446 if (kFlushWrites_PixelOp & pixelOpsFlags) { | |
447 this->flushSurfaceWrites(surface); | |
448 } | |
449 | |
450 return true; | 433 return true; |
451 } | 434 } |
452 | 435 |
453 bool GrContext::readSurfacePixels(GrSurface* src, | 436 bool GrContext::readSurfacePixels(GrSurface* src, |
454 int left, int top, int width, int height, | 437 int left, int top, int width, int height, |
455 GrPixelConfig dstConfig, void* buffer, size_t rowBytes, | 438 GrPixelConfig dstConfig, void* buffer, size_t rowBytes, |
456 uint32_t flags) { | 439 uint32_t flags) { |
457 RETURN_FALSE_IF_ABANDONED | 440 RETURN_FALSE_IF_ABANDONED |
458 ASSERT_OWNED_RESOURCE(src); | 441 ASSERT_OWNED_RESOURCE(src); |
459 SkASSERT(src); | 442 SkASSERT(src); |
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
736 ////////////////////////////////////////////////////////////////////////////// | 719 ////////////////////////////////////////////////////////////////////////////// |
737 | 720 |
738 void GrContext::addGpuTraceMarker(const GrGpuTraceMarker* marker) { | 721 void GrContext::addGpuTraceMarker(const GrGpuTraceMarker* marker) { |
739 fGpu->addGpuTraceMarker(marker); | 722 fGpu->addGpuTraceMarker(marker); |
740 } | 723 } |
741 | 724 |
742 void GrContext::removeGpuTraceMarker(const GrGpuTraceMarker* marker) { | 725 void GrContext::removeGpuTraceMarker(const GrGpuTraceMarker* marker) { |
743 fGpu->removeGpuTraceMarker(marker); | 726 fGpu->removeGpuTraceMarker(marker); |
744 } | 727 } |
745 | 728 |
OLD | NEW |