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 } |
332 | 349 |
333 // Trim the params here so that if we wind up making a temporary surface it
can be as small as | 350 // Trim the params here so that if we wind up making a temporary surface it
can be as small as |
334 // necessary and because GrGpu::getWritePixelsInfo requires it. | 351 // necessary. |
335 if (!GrSurfacePriv::AdjustWritePixelParams(surface->width(), surface->height
(), | 352 if (!GrSurfacePriv::AdjustWritePixelParams(surface->width(), surface->height
(), |
336 GrBytesPerPixel(srcConfig), &left
, &top, &width, | 353 GrBytesPerPixel(srcConfig), &left
, &top, &width, |
337 &height, &buffer, &rowBytes)) { | 354 &height, &buffer, &rowBytes)) { |
338 return false; | 355 return false; |
339 } | 356 } |
340 | 357 |
341 bool applyPremulToSrc = false; | 358 // If we didn't do a direct texture write then we upload the pixels to a tex
ture and draw. |
| 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; |
342 if (kUnpremul_PixelOpsFlag & pixelOpsFlags) { | 394 if (kUnpremul_PixelOpsFlag & pixelOpsFlags) { |
343 if (!GrPixelConfigIs8888(srcConfig)) { | 395 if (!GrPixelConfigIs8888(srcConfig)) { |
344 return false; | 396 return false; |
345 } | 397 } |
346 applyPremulToSrc = true; | 398 fp.reset(this->createUPMToPMEffect(paint.getProcessorDataManager(), text
ure, swapRAndB, |
347 } | 399 textureMatrix)); |
348 GrGpu::DrawPreference drawPreference = applyPremulToSrc ? | 400 // handle the unpremul step on the CPU if we couldn't create an effect t
o do it. |
349 GrGpu::kCallerPrefersDraw_DrawPrefer
ence : | 401 if (!fp) { |
350 GrGpu::kNoDraw_DrawPreference; | |
351 GrGpu::WritePixelTempDrawInfo tempDrawInfo; | |
352 if (!fGpu->getWritePixelsInfo(surface, width, height, rowBytes, srcConfig, &
drawPreference, | |
353 &tempDrawInfo)) { | |
354 return false; | |
355 } | |
356 | |
357 if (!(kDontFlush_PixelOpsFlag & pixelOpsFlags) && surface->surfacePriv().has
PendingIO()) { | |
358 this->flush(); | |
359 } | |
360 | |
361 SkAutoTUnref<GrTexture> tempTexture; | |
362 if (GrGpu::kNoDraw_DrawPreference != drawPreference) { | |
363 tempTexture.reset(this->textureProvider()->refScratchTexture( | |
364 tempDrawInfo.fTempSurfaceDesc, GrTextureProvider::kApprox_ScratchTex
Match)); | |
365 if (!tempTexture && GrGpu::kRequireDraw_DrawPreference == drawPreference
) { | |
366 return false; | |
367 } | |
368 } | |
369 | |
370 if (tempTexture) { | |
371 SkAutoTUnref<const GrFragmentProcessor> fp; | |
372 SkMatrix textureMatrix; | |
373 textureMatrix.setIDiv(tempTexture->width(), tempTexture->height()); | |
374 GrPaint paint; | |
375 if (applyPremulToSrc) { | |
376 fp.reset(this->createUPMToPMEffect(paint.getProcessorDataManager(),
tempTexture, | |
377 tempDrawInfo.fSwapRAndB, textureM
atrix)); | |
378 // If premultiplying was the only reason for the draw, fall back to
a straight write. | |
379 if (!fp && GrGpu::kCallerPrefersDraw_DrawPreference == drawPreferenc
e) { | |
380 tempTexture.reset(NULL); | |
381 } | |
382 } | |
383 if (tempTexture) { | |
384 if (!fp) { | |
385 fp.reset(GrConfigConversionEffect::Create( | |
386 paint.getProcessorDataManager(), tempTexture, tempDrawInfo.f
SwapRAndB, | |
387 GrConfigConversionEffect::kNone_PMConversion, textureMatrix)
); | |
388 if (!fp) { | |
389 return false; | |
390 } | |
391 } | |
392 GrRenderTarget* renderTarget = surface->asRenderTarget(); | |
393 SkASSERT(renderTarget); | |
394 if (tempTexture->surfacePriv().hasPendingIO()) { | |
395 this->flush(); | |
396 } | |
397 if (!fGpu->writeTexturePixels(tempTexture, 0, 0, width, height, | |
398 tempDrawInfo.fTempSurfaceDesc.fConfig,
buffer, | |
399 rowBytes)) { | |
400 return false; | |
401 } | |
402 SkMatrix matrix; | |
403 matrix.setTranslate(SkIntToScalar(left), SkIntToScalar(top)); | |
404 GrDrawContext* drawContext = this->drawContext(); | |
405 if (!drawContext) { | |
406 return false; | |
407 } | |
408 paint.addColorProcessor(fp); | |
409 SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(hei
ght)); | |
410 drawContext->drawRect(renderTarget, GrClip::WideOpen(), paint, matri
x, rect, NULL); | |
411 | |
412 if (kFlushWrites_PixelOp & pixelOpsFlags) { | |
413 this->flushSurfaceWrites(surface); | |
414 } | |
415 } | |
416 } | |
417 if (!tempTexture) { | |
418 SkASSERT(surface->asTexture()); | |
419 // allocate a tmp buffer and sw convert the pixels to premul | |
420 SkAutoSTMalloc<128 * 128, uint32_t> tmpPixels(0); | |
421 if (applyPremulToSrc) { | |
422 size_t tmpRowBytes = 4 * width; | 402 size_t tmpRowBytes = 4 * width; |
423 tmpPixels.reset(width * height); | 403 tmpPixels.reset(width * height); |
424 if (!sw_convert_to_premul(srcConfig, width, height, rowBytes, buffer
, tmpRowBytes, | 404 if (!sw_convert_to_premul(srcConfig, width, height, rowBytes, buffer
, tmpRowBytes, |
425 tmpPixels.get())) { | 405 tmpPixels.get())) { |
426 return false; | 406 return false; |
427 } | 407 } |
428 rowBytes = tmpRowBytes; | 408 rowBytes = tmpRowBytes; |
429 buffer = tmpPixels.get(); | 409 buffer = tmpPixels.get(); |
430 } | 410 } |
431 return fGpu->writeTexturePixels(surface->asTexture(), left, top, width,
height, srcConfig, | |
432 buffer, rowBytes); | |
433 } | 411 } |
| 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 |
434 return true; | 450 return true; |
435 } | 451 } |
436 | 452 |
437 bool GrContext::readSurfacePixels(GrSurface* src, | 453 bool GrContext::readSurfacePixels(GrSurface* src, |
438 int left, int top, int width, int height, | 454 int left, int top, int width, int height, |
439 GrPixelConfig dstConfig, void* buffer, size_t
rowBytes, | 455 GrPixelConfig dstConfig, void* buffer, size_t
rowBytes, |
440 uint32_t flags) { | 456 uint32_t flags) { |
441 RETURN_FALSE_IF_ABANDONED | 457 RETURN_FALSE_IF_ABANDONED |
442 ASSERT_OWNED_RESOURCE(src); | 458 ASSERT_OWNED_RESOURCE(src); |
443 SkASSERT(src); | 459 SkASSERT(src); |
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
720 ////////////////////////////////////////////////////////////////////////////// | 736 ////////////////////////////////////////////////////////////////////////////// |
721 | 737 |
722 void GrContext::addGpuTraceMarker(const GrGpuTraceMarker* marker) { | 738 void GrContext::addGpuTraceMarker(const GrGpuTraceMarker* marker) { |
723 fGpu->addGpuTraceMarker(marker); | 739 fGpu->addGpuTraceMarker(marker); |
724 } | 740 } |
725 | 741 |
726 void GrContext::removeGpuTraceMarker(const GrGpuTraceMarker* marker) { | 742 void GrContext::removeGpuTraceMarker(const GrGpuTraceMarker* marker) { |
727 fGpu->removeGpuTraceMarker(marker); | 743 fGpu->removeGpuTraceMarker(marker); |
728 } | 744 } |
729 | 745 |
OLD | NEW |