| 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 | 9 |
| 10 #include "GrContext.h" | 10 #include "GrContext.h" |
| (...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 263 return static_cast<GrStencilBuffer*>(resource); | 263 return static_cast<GrStencilBuffer*>(resource); |
| 264 } | 264 } |
| 265 | 265 |
| 266 static void stretchImage(void* dst, | 266 static void stretchImage(void* dst, |
| 267 int dstW, | 267 int dstW, |
| 268 int dstH, | 268 int dstH, |
| 269 void* src, | 269 void* src, |
| 270 int srcW, | 270 int srcW, |
| 271 int srcH, | 271 int srcH, |
| 272 size_t bpp) { | 272 size_t bpp) { |
| 273 GrFixed dx = (srcW << 16) / dstW; | 273 SkFixed dx = (srcW << 16) / dstW; |
| 274 GrFixed dy = (srcH << 16) / dstH; | 274 SkFixed dy = (srcH << 16) / dstH; |
| 275 | 275 |
| 276 GrFixed y = dy >> 1; | 276 SkFixed y = dy >> 1; |
| 277 | 277 |
| 278 size_t dstXLimit = dstW*bpp; | 278 size_t dstXLimit = dstW*bpp; |
| 279 for (int j = 0; j < dstH; ++j) { | 279 for (int j = 0; j < dstH; ++j) { |
| 280 GrFixed x = dx >> 1; | 280 SkFixed x = dx >> 1; |
| 281 void* srcRow = (uint8_t*)src + (y>>16)*srcW*bpp; | 281 void* srcRow = (uint8_t*)src + (y>>16)*srcW*bpp; |
| 282 void* dstRow = (uint8_t*)dst + j*dstW*bpp; | 282 void* dstRow = (uint8_t*)dst + j*dstW*bpp; |
| 283 for (size_t i = 0; i < dstXLimit; i += bpp) { | 283 for (size_t i = 0; i < dstXLimit; i += bpp) { |
| 284 memcpy((uint8_t*) dstRow + i, | 284 memcpy((uint8_t*) dstRow + i, |
| 285 (uint8_t*) srcRow + (x>>16)*bpp, | 285 (uint8_t*) srcRow + (x>>16)*bpp, |
| 286 bpp); | 286 bpp); |
| 287 x += dx; | 287 x += dx; |
| 288 } | 288 } |
| 289 y += dy; | 289 y += dy; |
| 290 } | 290 } |
| 291 } | 291 } |
| 292 | 292 |
| 293 namespace { | 293 namespace { |
| 294 | 294 |
| 295 // position + local coordinate | 295 // position + local coordinate |
| 296 extern const GrVertexAttrib gVertexAttribs[] = { | 296 extern const GrVertexAttrib gVertexAttribs[] = { |
| 297 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding
}, | 297 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding
}, |
| 298 {kVec2f_GrVertexAttribType, sizeof(GrPoint), kLocalCoord_GrVertexAttribBindi
ng} | 298 {kVec2f_GrVertexAttribType, sizeof(SkPoint), kLocalCoord_GrVertexAttribBindi
ng} |
| 299 }; | 299 }; |
| 300 | 300 |
| 301 }; | 301 }; |
| 302 | 302 |
| 303 // The desired texture is NPOT and tiled but that isn't supported by | 303 // The desired texture is NPOT and tiled but that isn't supported by |
| 304 // the current hardware. Resize the texture to be a POT | 304 // the current hardware. Resize the texture to be a POT |
| 305 GrTexture* GrContext::createResizedTexture(const GrTextureDesc& desc, | 305 GrTexture* GrContext::createResizedTexture(const GrTextureDesc& desc, |
| 306 const GrCacheID& cacheID, | 306 const GrCacheID& cacheID, |
| 307 void* srcData, | 307 void* srcData, |
| 308 size_t rowBytes, | 308 size_t rowBytes, |
| (...skipping 26 matching lines...) Expand all Loading... |
| 335 // the original. | 335 // the original. |
| 336 GrTextureParams params(SkShader::kClamp_TileMode, filter ? GrTexturePara
ms::kBilerp_FilterMode : | 336 GrTextureParams params(SkShader::kClamp_TileMode, filter ? GrTexturePara
ms::kBilerp_FilterMode : |
| 337 GrTexturePara
ms::kNone_FilterMode); | 337 GrTexturePara
ms::kNone_FilterMode); |
| 338 drawState->addColorTextureEffect(clampedTexture, SkMatrix::I(), params); | 338 drawState->addColorTextureEffect(clampedTexture, SkMatrix::I(), params); |
| 339 | 339 |
| 340 drawState->setVertexAttribs<gVertexAttribs>(SK_ARRAY_COUNT(gVertexAttrib
s)); | 340 drawState->setVertexAttribs<gVertexAttribs>(SK_ARRAY_COUNT(gVertexAttrib
s)); |
| 341 | 341 |
| 342 GrDrawTarget::AutoReleaseGeometry arg(fGpu, 4, 0); | 342 GrDrawTarget::AutoReleaseGeometry arg(fGpu, 4, 0); |
| 343 | 343 |
| 344 if (arg.succeeded()) { | 344 if (arg.succeeded()) { |
| 345 GrPoint* verts = (GrPoint*) arg.vertices(); | 345 SkPoint* verts = (SkPoint*) arg.vertices(); |
| 346 verts[0].setIRectFan(0, 0, texture->width(), texture->height(), 2 *
sizeof(GrPoint)); | 346 verts[0].setIRectFan(0, 0, texture->width(), texture->height(), 2 *
sizeof(SkPoint)); |
| 347 verts[1].setIRectFan(0, 0, 1, 1, 2 * sizeof(GrPoint)); | 347 verts[1].setIRectFan(0, 0, 1, 1, 2 * sizeof(SkPoint)); |
| 348 fGpu->drawNonIndexed(kTriangleFan_GrPrimitiveType, 0, 4); | 348 fGpu->drawNonIndexed(kTriangleFan_GrPrimitiveType, 0, 4); |
| 349 } | 349 } |
| 350 } else { | 350 } else { |
| 351 // TODO: Our CPU stretch doesn't filter. But we create separate | 351 // TODO: Our CPU stretch doesn't filter. But we create separate |
| 352 // stretched textures when the texture params is either filtered or | 352 // stretched textures when the texture params is either filtered or |
| 353 // not. Either implement filtered stretch blit on CPU or just create | 353 // not. Either implement filtered stretch blit on CPU or just create |
| 354 // one when FBO case fails. | 354 // one when FBO case fails. |
| 355 | 355 |
| 356 rtDesc.fFlags = kNone_GrTextureFlags; | 356 rtDesc.fFlags = kNone_GrTextureFlags; |
| 357 // no longer need to clamp at min RT size. | 357 // no longer need to clamp at min RT size. |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 432 !(inDesc.fFlags & kRenderTarget_GrTextureFlagBit)) { | 432 !(inDesc.fFlags & kRenderTarget_GrTextureFlagBit)) { |
| 433 // If we're never recycling this texture we can always make it the right
size | 433 // If we're never recycling this texture we can always make it the right
size |
| 434 return create_scratch_texture(fGpu, fTextureCache, inDesc); | 434 return create_scratch_texture(fGpu, fTextureCache, inDesc); |
| 435 } | 435 } |
| 436 | 436 |
| 437 GrTextureDesc desc = inDesc; | 437 GrTextureDesc desc = inDesc; |
| 438 | 438 |
| 439 if (kApprox_ScratchTexMatch == match) { | 439 if (kApprox_ScratchTexMatch == match) { |
| 440 // bin by pow2 with a reasonable min | 440 // bin by pow2 with a reasonable min |
| 441 static const int MIN_SIZE = 16; | 441 static const int MIN_SIZE = 16; |
| 442 desc.fWidth = GrMax(MIN_SIZE, GrNextPow2(desc.fWidth)); | 442 desc.fWidth = SkTMax(MIN_SIZE, GrNextPow2(desc.fWidth)); |
| 443 desc.fHeight = GrMax(MIN_SIZE, GrNextPow2(desc.fHeight)); | 443 desc.fHeight = SkTMax(MIN_SIZE, GrNextPow2(desc.fHeight)); |
| 444 } | 444 } |
| 445 | 445 |
| 446 GrResource* resource = NULL; | 446 GrResource* resource = NULL; |
| 447 int origWidth = desc.fWidth; | 447 int origWidth = desc.fWidth; |
| 448 int origHeight = desc.fHeight; | 448 int origHeight = desc.fHeight; |
| 449 | 449 |
| 450 do { | 450 do { |
| 451 GrResourceKey key = GrTexture::ComputeScratchKey(desc); | 451 GrResourceKey key = GrTexture::ComputeScratchKey(desc); |
| 452 // Ensure we have exclusive access to the texture so future 'find' calls
don't return it | 452 // Ensure we have exclusive access to the texture so future 'find' calls
don't return it |
| 453 resource = fTextureCache->find(key, GrResourceCache::kHide_OwnershipFlag
); | 453 resource = fTextureCache->find(key, GrResourceCache::kHide_OwnershipFlag
); |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 573 void GrContext::getTextureCacheLimits(int* maxTextures, | 573 void GrContext::getTextureCacheLimits(int* maxTextures, |
| 574 size_t* maxTextureBytes) const { | 574 size_t* maxTextureBytes) const { |
| 575 fTextureCache->getLimits(maxTextures, maxTextureBytes); | 575 fTextureCache->getLimits(maxTextures, maxTextureBytes); |
| 576 } | 576 } |
| 577 | 577 |
| 578 void GrContext::setTextureCacheLimits(int maxTextures, size_t maxTextureBytes) { | 578 void GrContext::setTextureCacheLimits(int maxTextures, size_t maxTextureBytes) { |
| 579 fTextureCache->setLimits(maxTextures, maxTextureBytes); | 579 fTextureCache->setLimits(maxTextures, maxTextureBytes); |
| 580 } | 580 } |
| 581 | 581 |
| 582 int GrContext::getMaxTextureSize() const { | 582 int GrContext::getMaxTextureSize() const { |
| 583 return GrMin(fGpu->caps()->maxTextureSize(), fMaxTextureSizeOverride); | 583 return SkTMin(fGpu->caps()->maxTextureSize(), fMaxTextureSizeOverride); |
| 584 } | 584 } |
| 585 | 585 |
| 586 int GrContext::getMaxRenderTargetSize() const { | 586 int GrContext::getMaxRenderTargetSize() const { |
| 587 return fGpu->caps()->maxRenderTargetSize(); | 587 return fGpu->caps()->maxRenderTargetSize(); |
| 588 } | 588 } |
| 589 | 589 |
| 590 int GrContext::getMaxSampleCount() const { | 590 int GrContext::getMaxSampleCount() const { |
| 591 return fGpu->caps()->maxSampleCount(); | 591 return fGpu->caps()->maxSampleCount(); |
| 592 } | 592 } |
| 593 | 593 |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 673 } | 673 } |
| 674 #endif | 674 #endif |
| 675 | 675 |
| 676 //////////////////////////////////////////////////////////////////////////////// | 676 //////////////////////////////////////////////////////////////////////////////// |
| 677 | 677 |
| 678 /* create a triangle strip that strokes the specified triangle. There are 8 | 678 /* create a triangle strip that strokes the specified triangle. There are 8 |
| 679 unique vertices, but we repreat the last 2 to close up. Alternatively we | 679 unique vertices, but we repreat the last 2 to close up. Alternatively we |
| 680 could use an indices array, and then only send 8 verts, but not sure that | 680 could use an indices array, and then only send 8 verts, but not sure that |
| 681 would be faster. | 681 would be faster. |
| 682 */ | 682 */ |
| 683 static void setStrokeRectStrip(GrPoint verts[10], SkRect rect, | 683 static void setStrokeRectStrip(SkPoint verts[10], SkRect rect, |
| 684 SkScalar width) { | 684 SkScalar width) { |
| 685 const SkScalar rad = SkScalarHalf(width); | 685 const SkScalar rad = SkScalarHalf(width); |
| 686 rect.sort(); | 686 rect.sort(); |
| 687 | 687 |
| 688 verts[0].set(rect.fLeft + rad, rect.fTop + rad); | 688 verts[0].set(rect.fLeft + rad, rect.fTop + rad); |
| 689 verts[1].set(rect.fLeft - rad, rect.fTop - rad); | 689 verts[1].set(rect.fLeft - rad, rect.fTop - rad); |
| 690 verts[2].set(rect.fRight - rad, rect.fTop + rad); | 690 verts[2].set(rect.fRight - rad, rect.fTop + rad); |
| 691 verts[3].set(rect.fRight + rad, rect.fTop - rad); | 691 verts[3].set(rect.fRight + rad, rect.fTop - rad); |
| 692 verts[4].set(rect.fRight - rad, rect.fBottom - rad); | 692 verts[4].set(rect.fRight - rad, rect.fBottom - rad); |
| 693 verts[5].set(rect.fRight + rad, rect.fBottom + rad); | 693 verts[5].set(rect.fRight + rad, rect.fBottom + rad); |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 849 target->drawState()->setDefaultVertexAttribs(); | 849 target->drawState()->setDefaultVertexAttribs(); |
| 850 GrDrawTarget::AutoReleaseGeometry geo(target, worstCaseVertCount, 0); | 850 GrDrawTarget::AutoReleaseGeometry geo(target, worstCaseVertCount, 0); |
| 851 | 851 |
| 852 if (!geo.succeeded()) { | 852 if (!geo.succeeded()) { |
| 853 GrPrintf("Failed to get space for vertices!\n"); | 853 GrPrintf("Failed to get space for vertices!\n"); |
| 854 return; | 854 return; |
| 855 } | 855 } |
| 856 | 856 |
| 857 GrPrimitiveType primType; | 857 GrPrimitiveType primType; |
| 858 int vertCount; | 858 int vertCount; |
| 859 GrPoint* vertex = geo.positions(); | 859 SkPoint* vertex = geo.positions(); |
| 860 | 860 |
| 861 if (width > 0) { | 861 if (width > 0) { |
| 862 vertCount = 10; | 862 vertCount = 10; |
| 863 primType = kTriangleStrip_GrPrimitiveType; | 863 primType = kTriangleStrip_GrPrimitiveType; |
| 864 setStrokeRectStrip(vertex, rect, width); | 864 setStrokeRectStrip(vertex, rect, width); |
| 865 } else { | 865 } else { |
| 866 // hairline | 866 // hairline |
| 867 vertCount = 5; | 867 vertCount = 5; |
| 868 primType = kLineStrip_GrPrimitiveType; | 868 primType = kLineStrip_GrPrimitiveType; |
| 869 vertex[0].set(rect.fLeft, rect.fTop); | 869 vertex[0].set(rect.fLeft, rect.fTop); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 897 | 897 |
| 898 GR_CREATE_TRACE_MARKER("GrContext::drawRectToRect", target); | 898 GR_CREATE_TRACE_MARKER("GrContext::drawRectToRect", target); |
| 899 | 899 |
| 900 target->drawRect(dstRect, dstMatrix, &localRect, localMatrix); | 900 target->drawRect(dstRect, dstMatrix, &localRect, localMatrix); |
| 901 } | 901 } |
| 902 | 902 |
| 903 namespace { | 903 namespace { |
| 904 | 904 |
| 905 extern const GrVertexAttrib gPosUVColorAttribs[] = { | 905 extern const GrVertexAttrib gPosUVColorAttribs[] = { |
| 906 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding }, | 906 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding }, |
| 907 {kVec2f_GrVertexAttribType, sizeof(GrPoint), kLocalCoord_GrVertexAttribBind
ing }, | 907 {kVec2f_GrVertexAttribType, sizeof(SkPoint), kLocalCoord_GrVertexAttribBind
ing }, |
| 908 {kVec4ub_GrVertexAttribType, 2*sizeof(GrPoint), kColor_GrVertexAttribBinding
} | 908 {kVec4ub_GrVertexAttribType, 2*sizeof(SkPoint), kColor_GrVertexAttribBinding
} |
| 909 }; | 909 }; |
| 910 | 910 |
| 911 extern const GrVertexAttrib gPosColorAttribs[] = { | 911 extern const GrVertexAttrib gPosColorAttribs[] = { |
| 912 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding}, | 912 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding}, |
| 913 {kVec4ub_GrVertexAttribType, sizeof(GrPoint), kColor_GrVertexAttribBinding}, | 913 {kVec4ub_GrVertexAttribType, sizeof(SkPoint), kColor_GrVertexAttribBinding}, |
| 914 }; | 914 }; |
| 915 | 915 |
| 916 static void set_vertex_attributes(GrDrawState* drawState, | 916 static void set_vertex_attributes(GrDrawState* drawState, |
| 917 const GrPoint* texCoords, | 917 const SkPoint* texCoords, |
| 918 const GrColor* colors, | 918 const GrColor* colors, |
| 919 int* colorOffset, | 919 int* colorOffset, |
| 920 int* texOffset) { | 920 int* texOffset) { |
| 921 *texOffset = -1; | 921 *texOffset = -1; |
| 922 *colorOffset = -1; | 922 *colorOffset = -1; |
| 923 | 923 |
| 924 if (NULL != texCoords && NULL != colors) { | 924 if (NULL != texCoords && NULL != colors) { |
| 925 *texOffset = sizeof(GrPoint); | 925 *texOffset = sizeof(SkPoint); |
| 926 *colorOffset = 2*sizeof(GrPoint); | 926 *colorOffset = 2*sizeof(SkPoint); |
| 927 drawState->setVertexAttribs<gPosUVColorAttribs>(3); | 927 drawState->setVertexAttribs<gPosUVColorAttribs>(3); |
| 928 } else if (NULL != texCoords) { | 928 } else if (NULL != texCoords) { |
| 929 *texOffset = sizeof(GrPoint); | 929 *texOffset = sizeof(SkPoint); |
| 930 drawState->setVertexAttribs<gPosUVColorAttribs>(2); | 930 drawState->setVertexAttribs<gPosUVColorAttribs>(2); |
| 931 } else if (NULL != colors) { | 931 } else if (NULL != colors) { |
| 932 *colorOffset = sizeof(GrPoint); | 932 *colorOffset = sizeof(SkPoint); |
| 933 drawState->setVertexAttribs<gPosColorAttribs>(2); | 933 drawState->setVertexAttribs<gPosColorAttribs>(2); |
| 934 } else { | 934 } else { |
| 935 drawState->setVertexAttribs<gPosColorAttribs>(1); | 935 drawState->setVertexAttribs<gPosColorAttribs>(1); |
| 936 } | 936 } |
| 937 } | 937 } |
| 938 | 938 |
| 939 }; | 939 }; |
| 940 | 940 |
| 941 void GrContext::drawVertices(const GrPaint& paint, | 941 void GrContext::drawVertices(const GrPaint& paint, |
| 942 GrPrimitiveType primitiveType, | 942 GrPrimitiveType primitiveType, |
| 943 int vertexCount, | 943 int vertexCount, |
| 944 const GrPoint positions[], | 944 const SkPoint positions[], |
| 945 const GrPoint texCoords[], | 945 const SkPoint texCoords[], |
| 946 const GrColor colors[], | 946 const GrColor colors[], |
| 947 const uint16_t indices[], | 947 const uint16_t indices[], |
| 948 int indexCount) { | 948 int indexCount) { |
| 949 AutoRestoreEffects are; | 949 AutoRestoreEffects are; |
| 950 AutoCheckFlush acf(this); | 950 AutoCheckFlush acf(this); |
| 951 GrDrawTarget::AutoReleaseGeometry geo; // must be inside AutoCheckFlush scop
e | 951 GrDrawTarget::AutoReleaseGeometry geo; // must be inside AutoCheckFlush scop
e |
| 952 | 952 |
| 953 GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf
); | 953 GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf
); |
| 954 | 954 |
| 955 GR_CREATE_TRACE_MARKER("GrContext::drawVertices", target); | 955 GR_CREATE_TRACE_MARKER("GrContext::drawVertices", target); |
| 956 | 956 |
| 957 GrDrawState* drawState = target->drawState(); | 957 GrDrawState* drawState = target->drawState(); |
| 958 | 958 |
| 959 int colorOffset = -1, texOffset = -1; | 959 int colorOffset = -1, texOffset = -1; |
| 960 set_vertex_attributes(drawState, texCoords, colors, &colorOffset, &texOffset
); | 960 set_vertex_attributes(drawState, texCoords, colors, &colorOffset, &texOffset
); |
| 961 | 961 |
| 962 size_t vertexSize = drawState->getVertexSize(); | 962 size_t vertexSize = drawState->getVertexSize(); |
| 963 if (sizeof(GrPoint) != vertexSize) { | 963 if (sizeof(SkPoint) != vertexSize) { |
| 964 if (!geo.set(target, vertexCount, 0)) { | 964 if (!geo.set(target, vertexCount, 0)) { |
| 965 GrPrintf("Failed to get space for vertices!\n"); | 965 GrPrintf("Failed to get space for vertices!\n"); |
| 966 return; | 966 return; |
| 967 } | 967 } |
| 968 void* curVertex = geo.vertices(); | 968 void* curVertex = geo.vertices(); |
| 969 | 969 |
| 970 for (int i = 0; i < vertexCount; ++i) { | 970 for (int i = 0; i < vertexCount; ++i) { |
| 971 *((GrPoint*)curVertex) = positions[i]; | 971 *((SkPoint*)curVertex) = positions[i]; |
| 972 | 972 |
| 973 if (texOffset >= 0) { | 973 if (texOffset >= 0) { |
| 974 *(GrPoint*)((intptr_t)curVertex + texOffset) = texCoords[i]; | 974 *(SkPoint*)((intptr_t)curVertex + texOffset) = texCoords[i]; |
| 975 } | 975 } |
| 976 if (colorOffset >= 0) { | 976 if (colorOffset >= 0) { |
| 977 *(GrColor*)((intptr_t)curVertex + colorOffset) = colors[i]; | 977 *(GrColor*)((intptr_t)curVertex + colorOffset) = colors[i]; |
| 978 } | 978 } |
| 979 curVertex = (void*)((intptr_t)curVertex + vertexSize); | 979 curVertex = (void*)((intptr_t)curVertex + vertexSize); |
| 980 } | 980 } |
| 981 } else { | 981 } else { |
| 982 target->setVertexSourceToArray(positions, vertexCount); | 982 target->setVertexSourceToArray(positions, vertexCount); |
| 983 } | 983 } |
| 984 | 984 |
| (...skipping 800 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1785 } | 1785 } |
| 1786 return path; | 1786 return path; |
| 1787 } | 1787 } |
| 1788 | 1788 |
| 1789 /////////////////////////////////////////////////////////////////////////////// | 1789 /////////////////////////////////////////////////////////////////////////////// |
| 1790 #if GR_CACHE_STATS | 1790 #if GR_CACHE_STATS |
| 1791 void GrContext::printCacheStats() const { | 1791 void GrContext::printCacheStats() const { |
| 1792 fTextureCache->printStats(); | 1792 fTextureCache->printStats(); |
| 1793 } | 1793 } |
| 1794 #endif | 1794 #endif |
| OLD | NEW |