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

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

Issue 882223003: Move npot resizing out of GrContext and simplify GrContext texture functions. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: rebase Created 5 years, 10 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 | « src/effects/SkColorCubeFilter.cpp ('k') | src/gpu/SkGr.cpp » ('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 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
216 if (fGpu->caps()->pathRenderingSupport() && renderTarget->getStencilBuffer() && 216 if (fGpu->caps()->pathRenderingSupport() && renderTarget->getStencilBuffer() &&
217 renderTarget->isMultisampled()) { 217 renderTarget->isMultisampled()) {
218 return GrStencilAndCoverTextContext::Create(this, leakyProperties); 218 return GrStencilAndCoverTextContext::Create(this, leakyProperties);
219 } 219 }
220 220
221 return GrDistanceFieldTextContext::Create(this, leakyProperties, enableDista nceFieldFonts); 221 return GrDistanceFieldTextContext::Create(this, leakyProperties, enableDista nceFieldFonts);
222 } 222 }
223 223
224 //////////////////////////////////////////////////////////////////////////////// 224 ////////////////////////////////////////////////////////////////////////////////
225 225
226 static void stretch_image(void* dst, 226 GrTexture* GrContext::createTexture(const GrSurfaceDesc& desc, const void* srcDa ta,
227 int dstW, 227 size_t rowBytes) {
228 int dstH, 228 return fGpu->createTexture(desc, true, srcData, rowBytes);
229 const void* src,
230 int srcW,
231 int srcH,
232 size_t bpp) {
233 SkFixed dx = (srcW << 16) / dstW;
234 SkFixed dy = (srcH << 16) / dstH;
235
236 SkFixed y = dy >> 1;
237
238 size_t dstXLimit = dstW*bpp;
239 for (int j = 0; j < dstH; ++j) {
240 SkFixed x = dx >> 1;
241 const uint8_t* srcRow = reinterpret_cast<const uint8_t *>(src) + (y>>16) *srcW*bpp;
242 uint8_t* dstRow = reinterpret_cast<uint8_t *>(dst) + j*dstW*bpp;
243 for (size_t i = 0; i < dstXLimit; i += bpp) {
244 memcpy(dstRow + i, srcRow + (x>>16)*bpp, bpp);
245 x += dx;
246 }
247 y += dy;
248 }
249 }
250
251 enum ResizeFlags {
252 /**
253 * The kStretchToPOT bit is set when the texture is NPOT and is being repeat ed or mipped but the
254 * hardware doesn't support that feature.
255 */
256 kStretchToPOT_ResizeFlag = 0x1,
257 /**
258 * The kBilerp bit can only be set when the kStretchToPOT flag is set and in dicates whether the
259 * stretched texture should be bilerped.
260 */
261 kBilerp_ResizeFlag = 0x2,
262 };
263
264 static uint32_t get_texture_flags(const GrGpu* gpu,
265 const GrTextureParams* params,
266 const GrSurfaceDesc& desc) {
267 uint32_t flags = 0;
268 bool tiled = params && params->isTiled();
269 if (tiled && !gpu->caps()->npotTextureTileSupport()) {
270 if (!SkIsPow2(desc.fWidth) || !SkIsPow2(desc.fHeight)) {
271 flags |= kStretchToPOT_ResizeFlag;
272 switch(params->filterMode()) {
273 case GrTextureParams::kNone_FilterMode:
274 break;
275 case GrTextureParams::kBilerp_FilterMode:
276 case GrTextureParams::kMipMap_FilterMode:
277 flags |= kBilerp_ResizeFlag;
278 break;
279 }
280 }
281 }
282 return flags;
283 }
284 // The desired texture is NPOT and tiled but that isn't supported by
285 // the current hardware. Resize the texture to be a POT
286 GrTexture* GrContext::createResizedTexture(const GrSurfaceDesc& desc,
287 const GrContentKey& origKey,
288 const void* srcData,
289 size_t rowBytes,
290 bool filter) {
291 SkAutoTUnref<GrTexture> clampedTexture(this->findAndRefTexture(desc, origKey , NULL));
292 if (NULL == clampedTexture) {
293 clampedTexture.reset(this->createTexture(NULL, desc, origKey, srcData, r owBytes));
294
295 if (NULL == clampedTexture) {
296 return NULL;
297 }
298 clampedTexture->cacheAccess().setContentKey(origKey);
299 }
300
301 GrSurfaceDesc rtDesc = desc;
302 rtDesc.fFlags = rtDesc.fFlags |
303 kRenderTarget_GrSurfaceFlag |
304 kNoStencil_GrSurfaceFlag;
305 rtDesc.fWidth = GrNextPow2(desc.fWidth);
306 rtDesc.fHeight = GrNextPow2(desc.fHeight);
307
308 GrTexture* texture = fGpu->createTexture(rtDesc, true, NULL, 0);
309
310 if (texture) {
311 GrPipelineBuilder pipelineBuilder;
312 pipelineBuilder.setRenderTarget(texture->asRenderTarget());
313
314 // if filtering is not desired then we want to ensure all
315 // texels in the resampled image are copies of texels from
316 // the original.
317 GrTextureParams params(SkShader::kClamp_TileMode,
318 filter ? GrTextureParams::kBilerp_FilterMode :
319 GrTextureParams::kNone_FilterMode);
320 pipelineBuilder.addColorTextureProcessor(clampedTexture, SkMatrix::I(), params);
321
322 uint32_t flags = GrDefaultGeoProcFactory::kPosition_GPType |
323 GrDefaultGeoProcFactory::kLocalCoord_GPType;
324 SkAutoTUnref<const GrGeometryProcessor> gp(
325 GrDefaultGeoProcFactory::Create(flags, GrColor_WHITE));
326
327 GrDrawTarget::AutoReleaseGeometry arg(fDrawBuffer, 4, gp->getVertexStrid e(), 0);
328 SkASSERT(gp->getVertexStride() == 2 * sizeof(SkPoint));
329
330 if (arg.succeeded()) {
331 SkPoint* verts = (SkPoint*) arg.vertices();
332 verts[0].setIRectFan(0, 0, texture->width(), texture->height(), 2 * sizeof(SkPoint));
333 verts[1].setIRectFan(0, 0, 1, 1, 2 * sizeof(SkPoint));
334 fDrawBuffer->drawNonIndexed(&pipelineBuilder, gp, kTriangleFan_GrPri mitiveType, 0, 4);
335 } else {
336 texture->unref();
337 texture = NULL;
338 }
339 } else {
340 // TODO: Our CPU stretch doesn't filter. But we create separate
341 // stretched textures when the texture params is either filtered or
342 // not. Either implement filtered stretch blit on CPU or just create
343 // one when FBO case fails.
344
345 rtDesc.fFlags = kNone_GrSurfaceFlags;
346 // no longer need to clamp at min RT size.
347 rtDesc.fWidth = GrNextPow2(desc.fWidth);
348 rtDesc.fHeight = GrNextPow2(desc.fHeight);
349
350 // We shouldn't be resizing a compressed texture.
351 SkASSERT(!GrPixelConfigIsCompressed(desc.fConfig));
352
353 size_t bpp = GrBytesPerPixel(desc.fConfig);
354 GrAutoMalloc<128*128*4> stretchedPixels(bpp * rtDesc.fWidth * rtDesc.fHe ight);
355 stretch_image(stretchedPixels.get(), rtDesc.fWidth, rtDesc.fHeight,
356 srcData, desc.fWidth, desc.fHeight, bpp);
357
358 size_t stretchedRowBytes = rtDesc.fWidth * bpp;
359
360 texture = fGpu->createTexture(rtDesc, true, stretchedPixels.get(), stret chedRowBytes);
361 SkASSERT(texture);
362 }
363
364 return texture;
365 }
366
367 static GrContentKey::Domain ResizeDomain() {
368 static const GrContentKey::Domain kDomain = GrContentKey::GenerateDomain();
369 return kDomain;
370 }
371
372 GrTexture* GrContext::createTexture(const GrTextureParams* params,
373 const GrSurfaceDesc& desc,
374 const GrContentKey& origKey,
375 const void* srcData,
376 size_t rowBytes,
377 GrContentKey* outKey) {
378 GrTexture* texture;
379 uint32_t flags = get_texture_flags(fGpu, params, desc);
380 SkTCopyOnFirstWrite<GrContentKey> key(origKey);
381 if (flags) {
382 // We don't have a code path to resize compressed textures.
383 if (GrPixelConfigIsCompressed(desc.fConfig)) {
384 return NULL;
385 }
386 texture = this->createResizedTexture(desc, origKey, srcData, rowBytes,
387 SkToBool(flags & kBilerp_ResizeFlag ));
388
389 GrContentKey::Builder builder(key.writable(), origKey, ResizeDomain(), 1 );
390 builder[0] = flags;
391
392 } else {
393 texture = fGpu->createTexture(desc, true, srcData, rowBytes);
394 }
395
396 if (texture) {
397 if (texture->cacheAccess().setContentKey(*key)) {
398 if (outKey) {
399 *outKey = *key;
400 }
401 } else {
402 texture->unref();
403 texture = NULL;
404 }
405 }
406
407 return texture;
408 }
409
410 GrTexture* GrContext::findAndRefTexture(const GrSurfaceDesc& desc,
411 const GrContentKey& origKey,
412 const GrTextureParams* params) {
413 uint32_t flags = get_texture_flags(fGpu, params, desc);
414 SkTCopyOnFirstWrite<GrContentKey> key(origKey);
415 if (flags) {
416 GrContentKey::Builder builder(key.writable(), origKey, ResizeDomain(), 1 );
417 builder[0] = flags;
418 }
419
420 GrGpuResource* resource = this->findAndRefCachedResource(*key);
421 if (resource) {
422 SkASSERT(static_cast<GrSurface*>(resource)->asTexture());
423 return static_cast<GrSurface*>(resource)->asTexture();
424 }
425 return NULL;
426 }
427
428 bool GrContext::isTextureInCache(const GrSurfaceDesc& desc,
429 const GrContentKey& origKey,
430 const GrTextureParams* params) const {
431 uint32_t flags = get_texture_flags(fGpu, params, desc);
432 SkTCopyOnFirstWrite<GrContentKey> key(origKey);
433 if (flags) {
434 GrContentKey::Builder builder(key.writable(), origKey, ResizeDomain(), 1 );
435 builder[0] = flags;
436 }
437
438 return fResourceCache2->hasContentKey(*key);
439 } 229 }
440 230
441 GrTexture* GrContext::refScratchTexture(const GrSurfaceDesc& inDesc, ScratchTexM atch match, 231 GrTexture* GrContext::refScratchTexture(const GrSurfaceDesc& inDesc, ScratchTexM atch match,
442 bool calledDuringFlush) { 232 bool calledDuringFlush) {
443 // kNoStencil has no meaning if kRT isn't set. 233 // kNoStencil has no meaning if kRT isn't set.
444 SkASSERT((inDesc.fFlags & kRenderTarget_GrSurfaceFlag) || 234 SkASSERT((inDesc.fFlags & kRenderTarget_GrSurfaceFlag) ||
445 !(inDesc.fFlags & kNoStencil_GrSurfaceFlag)); 235 !(inDesc.fFlags & kNoStencil_GrSurfaceFlag));
446 236
447 // Make sure caller has checked for renderability if kRT is set. 237 // Make sure caller has checked for renderability if kRT is set.
448 SkASSERT(!(inDesc.fFlags & kRenderTarget_GrSurfaceFlag) || 238 SkASSERT(!(inDesc.fFlags & kRenderTarget_GrSurfaceFlag) ||
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
519 // Flush the InOrderDrawBuffer to possibly free up some textures 309 // Flush the InOrderDrawBuffer to possibly free up some textures
520 context->fFlushToReduceCacheSize = true; 310 context->fFlushToReduceCacheSize = true;
521 } 311 }
522 312
523 GrTexture* GrContext::createUncachedTexture(const GrSurfaceDesc& desc, 313 GrTexture* GrContext::createUncachedTexture(const GrSurfaceDesc& desc,
524 void* srcData, 314 void* srcData,
525 size_t rowBytes) { 315 size_t rowBytes) {
526 return fGpu->createTexture(desc, false, srcData, rowBytes); 316 return fGpu->createTexture(desc, false, srcData, rowBytes);
527 } 317 }
528 318
529 void GrContext::getResourceCacheLimits(int* maxTextures, size_t* maxTextureBytes ) const {
530 if (maxTextures) {
531 *maxTextures = fResourceCache2->getMaxResourceCount();
532 }
533 if (maxTextureBytes) {
534 *maxTextureBytes = fResourceCache2->getMaxResourceBytes();
535 }
536 }
537
538 void GrContext::setResourceCacheLimits(int maxTextures, size_t maxTextureBytes) {
539 fResourceCache2->setLimits(maxTextures, maxTextureBytes);
540 }
541
542 int GrContext::getMaxTextureSize() const { 319 int GrContext::getMaxTextureSize() const {
543 return SkTMin(fGpu->caps()->maxTextureSize(), fMaxTextureSizeOverride); 320 return SkTMin(fGpu->caps()->maxTextureSize(), fMaxTextureSizeOverride);
544 } 321 }
545 322
546 int GrContext::getMaxRenderTargetSize() const { 323 int GrContext::getMaxRenderTargetSize() const {
547 return fGpu->caps()->maxRenderTargetSize(); 324 return fGpu->caps()->maxRenderTargetSize();
548 } 325 }
549 326
550 int GrContext::getMaxSampleCount() const { 327 int GrContext::getMaxSampleCount() const {
551 return fGpu->caps()->maxSampleCount(); 328 return fGpu->caps()->maxSampleCount();
552 } 329 }
553 330
554 /////////////////////////////////////////////////////////////////////////////// 331 ///////////////////////////////////////////////////////////////////////////////
555 332
556 GrTexture* GrContext::wrapBackendTexture(const GrBackendTextureDesc& desc) { 333 GrTexture* GrContext::wrapBackendTexture(const GrBackendTextureDesc& desc) {
557 return fGpu->wrapBackendTexture(desc); 334 return fGpu->wrapBackendTexture(desc);
558 } 335 }
559 336
560 GrRenderTarget* GrContext::wrapBackendRenderTarget(const GrBackendRenderTargetDe sc& desc) { 337 GrRenderTarget* GrContext::wrapBackendRenderTarget(const GrBackendRenderTargetDe sc& desc) {
561 return fGpu->wrapBackendRenderTarget(desc); 338 return fGpu->wrapBackendRenderTarget(desc);
562 } 339 }
563 340
564 /////////////////////////////////////////////////////////////////////////////// 341 ///////////////////////////////////////////////////////////////////////////////
565 342
566 bool GrContext::supportsIndex8PixelConfig(const GrTextureParams* params, 343 bool GrContext::supportsIndex8PixelConfig() const {
567 int width, int height) const {
568 const GrDrawTargetCaps* caps = fGpu->caps(); 344 const GrDrawTargetCaps* caps = fGpu->caps();
569 if (!caps->isConfigTexturable(kIndex_8_GrPixelConfig)) { 345 return caps->isConfigTexturable(kIndex_8_GrPixelConfig);
570 return false;
571 }
572
573 bool isPow2 = SkIsPow2(width) && SkIsPow2(height);
574
575 if (!isPow2) {
576 bool tiled = params && params->isTiled();
577 if (tiled && !caps->npotTextureTileSupport()) {
578 return false;
579 }
580 }
581 return true;
582 } 346 }
583 347
584 348
585 //////////////////////////////////////////////////////////////////////////////// 349 ////////////////////////////////////////////////////////////////////////////////
586 350
587 void GrContext::clear(const SkIRect* rect, 351 void GrContext::clear(const SkIRect* rect,
588 const GrColor color, 352 const GrColor color,
589 bool canIgnoreRect, 353 bool canIgnoreRect,
590 GrRenderTarget* renderTarget) { 354 GrRenderTarget* renderTarget) {
591 ASSERT_OWNED_RESOURCE(renderTarget); 355 ASSERT_OWNED_RESOURCE(renderTarget);
(...skipping 1168 matching lines...) Expand 10 before | Expand all | Expand 10 after
1760 } 1524 }
1761 GrConfigConversionEffect::PMConversion upmToPM = 1525 GrConfigConversionEffect::PMConversion upmToPM =
1762 static_cast<GrConfigConversionEffect::PMConversion>(fUPMToPMConversion); 1526 static_cast<GrConfigConversionEffect::PMConversion>(fUPMToPMConversion);
1763 if (GrConfigConversionEffect::kNone_PMConversion != upmToPM) { 1527 if (GrConfigConversionEffect::kNone_PMConversion != upmToPM) {
1764 return GrConfigConversionEffect::Create(texture, swapRAndB, upmToPM, mat rix); 1528 return GrConfigConversionEffect::Create(texture, swapRAndB, upmToPM, mat rix);
1765 } else { 1529 } else {
1766 return NULL; 1530 return NULL;
1767 } 1531 }
1768 } 1532 }
1769 1533
1770 void GrContext::addResourceToCache(const GrContentKey& key, GrGpuResource* resou rce) { 1534 //////////////////////////////////////////////////////////////////////////////
1771 resource->cacheAccess().setContentKey(key); 1535
1536 void GrContext::getResourceCacheLimits(int* maxTextures, size_t* maxTextureBytes ) const {
1537 if (maxTextures) {
1538 *maxTextures = fResourceCache2->getMaxResourceCount();
1539 }
1540 if (maxTextureBytes) {
1541 *maxTextureBytes = fResourceCache2->getMaxResourceBytes();
1542 }
1543 }
1544
1545 void GrContext::setResourceCacheLimits(int maxTextures, size_t maxTextureBytes) {
1546 fResourceCache2->setLimits(maxTextures, maxTextureBytes);
1547 }
1548
1549 bool GrContext::addResourceToCache(const GrContentKey& key, GrGpuResource* resou rce) {
1550 ASSERT_OWNED_RESOURCE(resource);
1551 if (!resource || resource->wasDestroyed()) {
1552 return false;
1553 }
1554 return resource->cacheAccess().setContentKey(key);
1555 }
1556
1557 bool GrContext::isResourceInCache(const GrContentKey& key) const {
1558 return fResourceCache2->hasContentKey(key);
1772 } 1559 }
1773 1560
1774 GrGpuResource* GrContext::findAndRefCachedResource(const GrContentKey& key) { 1561 GrGpuResource* GrContext::findAndRefCachedResource(const GrContentKey& key) {
1775 return fResourceCache2->findAndRefContentResource(key); 1562 return fResourceCache2->findAndRefContentResource(key);
1776 } 1563 }
1777 1564
1565 //////////////////////////////////////////////////////////////////////////////
1566
1778 void GrContext::addGpuTraceMarker(const GrGpuTraceMarker* marker) { 1567 void GrContext::addGpuTraceMarker(const GrGpuTraceMarker* marker) {
1779 fGpu->addGpuTraceMarker(marker); 1568 fGpu->addGpuTraceMarker(marker);
1780 if (fDrawBuffer) { 1569 if (fDrawBuffer) {
1781 fDrawBuffer->addGpuTraceMarker(marker); 1570 fDrawBuffer->addGpuTraceMarker(marker);
1782 } 1571 }
1783 } 1572 }
1784 1573
1785 void GrContext::removeGpuTraceMarker(const GrGpuTraceMarker* marker) { 1574 void GrContext::removeGpuTraceMarker(const GrGpuTraceMarker* marker) {
1786 fGpu->removeGpuTraceMarker(marker); 1575 fGpu->removeGpuTraceMarker(marker);
1787 if (fDrawBuffer) { 1576 if (fDrawBuffer) {
1788 fDrawBuffer->removeGpuTraceMarker(marker); 1577 fDrawBuffer->removeGpuTraceMarker(marker);
1789 } 1578 }
1790 } 1579 }
1791 1580
1792 /////////////////////////////////////////////////////////////////////////////// 1581 ///////////////////////////////////////////////////////////////////////////////
1793 #if GR_CACHE_STATS 1582 #if GR_CACHE_STATS
1794 void GrContext::printCacheStats() const { 1583 void GrContext::printCacheStats() const {
1795 fResourceCache2->printStats(); 1584 fResourceCache2->printStats();
1796 } 1585 }
1797 #endif 1586 #endif
1798 1587
1799 #if GR_GPU_STATS 1588 #if GR_GPU_STATS
1800 const GrContext::GPUStats* GrContext::gpuStats() const { 1589 const GrContext::GPUStats* GrContext::gpuStats() const {
1801 return fGpu->gpuStats(); 1590 return fGpu->gpuStats();
1802 } 1591 }
1803 #endif 1592 #endif
1804 1593
OLDNEW
« no previous file with comments | « src/effects/SkColorCubeFilter.cpp ('k') | src/gpu/SkGr.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698