Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(94)

Side by Side Diff: src/gpu/GrContext.cpp

Issue 1257073003: Move draw on upload decision in GrGpu (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: fixed for sw conversion case Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/gpu/GrGpu.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
358 // If we didn't do a direct texture write then we upload the pixels to a tex ture and draw. 341 bool applyPremulToSrc = 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)) {
396 return false; 344 return false;
397 } 345 }
398 fp.reset(this->createUPMToPMEffect(paint.getProcessorDataManager(), text ure, swapRAndB, 346 applyPremulToSrc = 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 = applyPremulToSrc ?
401 if (!fp) { 349 GrGpu::kCallerPrefersDraw_DrawPrefer ence :
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 // temp buffer for doing sw premul conversion, if needed.
371 SkAutoSTMalloc<128 * 128, uint32_t> tmpPixels(0);
372 if (tempTexture) {
373 SkAutoTUnref<const GrFragmentProcessor> fp;
374 SkMatrix textureMatrix;
375 textureMatrix.setIDiv(tempTexture->width(), tempTexture->height());
376 GrPaint paint;
377 if (applyPremulToSrc) {
378 fp.reset(this->createUPMToPMEffect(paint.getProcessorDataManager(), tempTexture,
379 tempDrawInfo.fSwapRAndB, textureM atrix));
380 // If premultiplying was the only reason for the draw, fall back to a straight write.
381 if (!fp) {
382 if (GrGpu::kCallerPrefersDraw_DrawPreference == drawPreference) {
383 tempTexture.reset(NULL);
384 }
385 } else {
386 applyPremulToSrc = false;
387 }
388 }
389 if (tempTexture) {
390 if (!fp) {
391 fp.reset(GrConfigConversionEffect::Create(
392 paint.getProcessorDataManager(), tempTexture, tempDrawInfo.f SwapRAndB,
393 GrConfigConversionEffect::kNone_PMConversion, textureMatrix) );
394 if (!fp) {
395 return false;
396 }
397 }
398 GrRenderTarget* renderTarget = surface->asRenderTarget();
399 SkASSERT(renderTarget);
400 if (tempTexture->surfacePriv().hasPendingIO()) {
401 this->flush();
402 }
403 if (applyPremulToSrc) {
404 size_t tmpRowBytes = 4 * width;
405 tmpPixels.reset(width * height);
406 if (!sw_convert_to_premul(srcConfig, width, height, rowBytes, bu ffer, tmpRowBytes,
407 tmpPixels.get())) {
408 return false;
409 }
410 rowBytes = tmpRowBytes;
411 buffer = tmpPixels.get();
412 applyPremulToSrc = false;
413 }
414 if (!fGpu->writeTexturePixels(tempTexture, 0, 0, width, height,
415 tempDrawInfo.fTempSurfaceDesc.fConfig, buffer,
416 rowBytes)) {
417 return false;
418 }
419 SkMatrix matrix;
420 matrix.setTranslate(SkIntToScalar(left), SkIntToScalar(top));
421 GrDrawContext* drawContext = this->drawContext();
422 if (!drawContext) {
423 return false;
424 }
425 paint.addColorProcessor(fp);
426 SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(hei ght));
427 drawContext->drawRect(renderTarget, GrClip::WideOpen(), paint, matri x, rect, NULL);
428
429 if (kFlushWrites_PixelOp & pixelOpsFlags) {
430 this->flushSurfaceWrites(surface);
431 }
432 }
433 }
434 if (!tempTexture) {
435 SkASSERT(surface->asTexture());
436 if (applyPremulToSrc) {
402 size_t tmpRowBytes = 4 * width; 437 size_t tmpRowBytes = 4 * width;
403 tmpPixels.reset(width * height); 438 tmpPixels.reset(width * height);
404 if (!sw_convert_to_premul(srcConfig, width, height, rowBytes, buffer , tmpRowBytes, 439 if (!sw_convert_to_premul(srcConfig, width, height, rowBytes, buffer , tmpRowBytes,
405 tmpPixels.get())) { 440 tmpPixels.get())) {
406 return false; 441 return false;
407 } 442 }
408 rowBytes = tmpRowBytes; 443 rowBytes = tmpRowBytes;
409 buffer = tmpPixels.get(); 444 buffer = tmpPixels.get();
445 applyPremulToSrc = false;
410 } 446 }
447 return fGpu->writeTexturePixels(surface->asTexture(), left, top, width, height, srcConfig,
448 buffer, rowBytes);
411 } 449 }
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; 450 return true;
451 } 451 }
452 452
453 bool GrContext::readSurfacePixels(GrSurface* src, 453 bool GrContext::readSurfacePixels(GrSurface* src,
454 int left, int top, int width, int height, 454 int left, int top, int width, int height,
455 GrPixelConfig dstConfig, void* buffer, size_t rowBytes, 455 GrPixelConfig dstConfig, void* buffer, size_t rowBytes,
456 uint32_t flags) { 456 uint32_t flags) {
457 RETURN_FALSE_IF_ABANDONED 457 RETURN_FALSE_IF_ABANDONED
458 ASSERT_OWNED_RESOURCE(src); 458 ASSERT_OWNED_RESOURCE(src);
459 SkASSERT(src); 459 SkASSERT(src);
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
736 ////////////////////////////////////////////////////////////////////////////// 736 //////////////////////////////////////////////////////////////////////////////
737 737
738 void GrContext::addGpuTraceMarker(const GrGpuTraceMarker* marker) { 738 void GrContext::addGpuTraceMarker(const GrGpuTraceMarker* marker) {
739 fGpu->addGpuTraceMarker(marker); 739 fGpu->addGpuTraceMarker(marker);
740 } 740 }
741 741
742 void GrContext::removeGpuTraceMarker(const GrGpuTraceMarker* marker) { 742 void GrContext::removeGpuTraceMarker(const GrGpuTraceMarker* marker) {
743 fGpu->removeGpuTraceMarker(marker); 743 fGpu->removeGpuTraceMarker(marker);
744 } 744 }
745 745
OLDNEW
« no previous file with comments | « no previous file | src/gpu/GrGpu.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698