From d8702b0c560505a7ee2125db1364d6e8a24a8eba Mon Sep 17 00:00:00 2001 From: Fraser Gordon Date: Thu, 9 Mar 2017 19:52:12 -0500 Subject: [PATCH 1/7] Update libSkia to upstream HEAD (2nd Dec 2016) See libskia/git-revision.txt for commit hash. (cherry picked from commit e9fe1b9719fcd53f8e5ab9e18dc423d5a593306c) --- libskia/git-revision.txt | 1 + libskia/include/android/SkBRDAllocator.h | 29 + .../include/android/SkBitmapRegionDecoder.h | 88 + libskia/include/animator/SkAnimator.h | 501 ++ libskia/include/animator/SkAnimatorView.h | 39 + libskia/include/c/sk_canvas.h | 159 + libskia/include/c/sk_data.h | 70 + libskia/include/c/sk_image.h | 71 + libskia/include/c/sk_maskfilter.h | 47 + libskia/include/c/sk_matrix.h | 49 + libskia/include/c/sk_paint.h | 145 + libskia/include/c/sk_path.h | 84 + libskia/include/c/sk_picture.h | 70 + libskia/include/c/sk_shader.h | 143 + libskia/include/c/sk_surface.h | 73 + libskia/include/c/sk_types.h | 217 + libskia/include/codec/SkAndroidCodec.h | 265 + libskia/include/codec/SkCodec.h | 868 +++ libskia/include/codec/SkEncodedInfo.h | 199 + libskia/include/config/SkUserConfig.h | 137 +- libskia/include/config/sk_stdint.h | 1 - libskia/include/core/Sk64.h | 188 - .../include/core/SkAdvancedTypefaceMetrics.h | 156 - libskia/include/core/SkAnnotation.h | 72 +- libskia/include/core/SkBBHFactory.h | 31 + libskia/include/core/SkBitmap.h | 641 +-- libskia/include/core/SkBitmapDevice.h | 250 +- libskia/include/core/SkBlendMode.h | 58 + libskia/include/core/SkBlitRow.h | 51 +- libskia/include/core/SkBlurTypes.h | 29 + libskia/include/core/SkBounder.h | 93 - libskia/include/core/SkCanvas.h | 1516 ++++-- libskia/include/core/SkChecksum.h | 135 - libskia/include/core/SkClipOp.h | 26 + libskia/include/core/SkClipStack.h | 233 +- libskia/include/core/SkColor.h | 49 +- libskia/include/core/SkColorFilter.h | 118 +- libskia/include/core/SkColorPriv.h | 292 +- libskia/include/core/SkColorShader.h | 69 - libskia/include/core/SkColorSpace.h | 144 + libskia/include/core/SkColorSpaceXform.h | 61 + libskia/include/core/SkColorTable.h | 92 +- libskia/include/core/SkComposeShader.h | 58 - libskia/include/core/SkData.h | 99 +- libskia/include/core/SkDataTable.h | 21 +- libskia/include/core/SkDevice.h | 436 +- libskia/include/core/SkDeviceProperties.h | 112 - libskia/include/core/SkDocument.h | 168 +- libskia/include/core/SkDraw.h | 63 +- libskia/include/core/SkDrawFilter.h | 4 +- libskia/include/core/SkDrawLooper.h | 84 +- libskia/include/core/SkDrawable.h | 81 + libskia/include/core/SkEmptyShader.h | 43 - libskia/include/core/SkEncodedImageFormat.h | 33 + libskia/include/core/SkError.h | 91 - libskia/include/core/SkFilterQuality.h | 26 + libskia/include/core/SkFlate.h | 52 - libskia/include/core/SkFlattenable.h | 88 +- libskia/include/core/SkFlattenableBuffers.h | 260 - .../include/core/SkFlattenableSerialization.h | 3 + libskia/include/core/SkFloatingPoint.h | 140 - libskia/include/core/SkFont.h | 176 + libskia/include/core/SkFontHost.h | 131 - libskia/include/core/SkFontLCDConfig.h | 2 +- libskia/include/{ports => core}/SkFontStyle.h | 29 +- libskia/include/core/SkGraphics.h | 86 +- libskia/include/core/SkImage.h | 425 +- libskia/include/core/SkImageDecoder.h | 543 -- libskia/include/core/SkImageDeserializer.h | 36 + libskia/include/core/SkImageEncoder.h | 144 +- libskia/include/core/SkImageFilter.h | 400 +- libskia/include/core/SkImageFilterUtils.h | 38 - libskia/include/core/SkImageGenerator.h | 293 +- libskia/include/core/SkImageInfo.h | 289 +- libskia/include/core/SkInstCnt.h | 127 - libskia/include/core/SkLights.h | 199 + libskia/include/core/SkMallocPixelRef.h | 44 +- libskia/include/core/SkMask.h | 22 +- libskia/include/core/SkMaskFilter.h | 141 +- libskia/include/core/SkMath.h | 130 +- libskia/include/core/SkMatrix.h | 261 +- libskia/include/{utils => core}/SkMatrix44.h | 87 +- libskia/include/core/SkMetaData.h | 2 +- .../core/SkMilestone.h} | 10 +- libskia/include/core/SkMultiPictureDraw.h | 75 + libskia/include/core/SkOSFile.h | 101 +- libskia/include/core/SkPackBits.h | 79 - libskia/include/core/SkPaint.h | 529 +- libskia/include/core/SkPaintOptionsAndroid.h | 131 - libskia/include/core/SkPath.h | 499 +- libskia/include/core/SkPathEffect.h | 108 +- libskia/include/core/SkPathMeasure.h | 26 +- libskia/include/core/SkPathRef.h | 192 +- libskia/include/core/SkPicture.h | 363 +- libskia/include/core/SkPictureAnalyzer.h | 66 + libskia/include/core/SkPictureRecorder.h | 129 + libskia/include/core/SkPixelRef.h | 284 +- libskia/include/core/SkPixelSerializer.h | 50 + libskia/include/core/SkPixmap.h | 266 + libskia/include/core/SkPngChunkReader.h | 45 + libskia/include/core/SkPoint.h | 67 +- libskia/include/core/SkPoint3.h | 124 + libskia/include/core/SkPostConfig.h | 236 +- libskia/include/core/SkPreConfig.h | 151 +- libskia/include/core/SkRRect.h | 124 +- libskia/include/core/SkRSXform.h | 67 + libskia/include/core/SkRWBuffer.h | 107 + libskia/include/core/SkRasterizer.h | 7 +- libskia/include/core/SkRect.h | 230 +- libskia/include/core/SkRefCnt.h | 401 +- libskia/include/core/SkRegion.h | 17 +- libskia/include/core/SkScalar.h | 301 +- libskia/include/core/SkShader.h | 535 +- libskia/include/core/SkStream.h | 215 +- libskia/include/core/SkString.h | 54 +- libskia/include/core/SkStrokeRec.h | 79 +- libskia/include/core/SkSurface.h | 219 +- libskia/include/core/SkSurfaceProps.h | 82 + libskia/include/core/SkSwizzle.h | 19 + libskia/include/core/SkTLazy.h | 91 +- libskia/include/core/SkTextBlob.h | 239 + libskia/include/core/SkThread.h | 103 - libskia/include/core/SkTileGridPicture.h | 56 - libskia/include/core/SkTime.h | 38 +- libskia/include/core/SkTrace.h | 45 - libskia/include/core/SkTraceMemoryDump.h | 80 + libskia/include/core/SkTypeface.h | 208 +- libskia/include/core/SkTypes.h | 339 +- libskia/include/core/SkUnPreMultiply.h | 2 + libskia/include/core/SkUnitMapper.h | 37 - libskia/include/core/SkWriteBuffer.h | 155 + libskia/include/core/SkWriter32.h | 252 +- libskia/include/core/SkXfermode.h | 285 - libskia/include/core/SkYUVSizeInfo.h | 34 + libskia/include/device/xps/SkConstexprMath.h | 54 - libskia/include/effects/Sk1DPathEffect.h | 21 +- libskia/include/effects/Sk2DPathEffect.h | 40 +- .../include/effects/SkAlphaThresholdFilter.h | 32 + libskia/include/effects/SkArcToPathEffect.h | 40 + libskia/include/effects/SkArithmeticMode.h | 26 +- libskia/include/effects/SkAvoidXfermode.h | 65 - .../include/effects/SkBicubicImageFilter.h | 56 - libskia/include/effects/SkBitmapSource.h | 33 - libskia/include/effects/SkBlurDrawLooper.h | 44 +- libskia/include/effects/SkBlurImageFilter.h | 29 +- libskia/include/effects/SkBlurMaskFilter.h | 69 +- libskia/include/effects/SkColorCubeFilter.h | 77 + .../effects/SkColorFilterImageFilter.h | 30 +- libskia/include/effects/SkColorMatrix.h | 22 +- libskia/include/effects/SkColorMatrixFilter.h | 45 +- .../include/effects/SkComposeImageFilter.h | 19 +- libskia/include/effects/SkCornerPathEffect.h | 18 +- libskia/include/effects/SkDashPathEffect.h | 25 +- .../include/effects/SkDiscretePathEffect.h | 27 +- .../include/effects/SkDisplacementMapEffect.h | 48 +- .../include/effects/SkDropShadowImageFilter.h | 36 +- libskia/include/effects/SkEmbossMaskFilter.h | 19 +- libskia/include/effects/SkGammaColorFilter.h | 44 + .../include/effects/SkGaussianEdgeShader.h | 27 + libskia/include/effects/SkGradientShader.h | 175 +- libskia/include/effects/SkImageSource.h | 47 + .../include/effects/SkKernel33MaskFilter.h | 62 - libskia/include/effects/SkLayerDrawLooper.h | 119 +- libskia/include/effects/SkLayerRasterizer.h | 67 +- libskia/include/effects/SkLerpXfermode.h | 46 - .../include/effects/SkLightingImageFilter.h | 80 +- libskia/include/effects/SkLumaColorFilter.h | 16 +- .../include/effects/SkMagnifierImageFilter.h | 21 +- .../effects/SkMatrixConvolutionImageFilter.h | 96 +- libskia/include/effects/SkMergeImageFilter.h | 34 +- .../include/effects/SkMorphologyImageFilter.h | 85 +- libskia/include/effects/SkOffsetImageFilter.h | 25 +- .../include/effects/SkPaintFlagsDrawFilter.h | 2 +- libskia/include/effects/SkPaintImageFilter.h | 45 + libskia/include/effects/SkPerlinNoiseShader.h | 82 +- .../include/effects/SkPictureImageFilter.h | 56 +- libskia/include/effects/SkPixelXorXfermode.h | 38 - libskia/include/effects/SkPorterDuff.h | 79 - .../effects/SkRRectsGaussianEdgeMaskFilter.h | 36 + .../include/effects/SkRectShaderImageFilter.h | 50 - libskia/include/effects/SkShadowMaskFilter.h | 51 + libskia/include/effects/SkStippleMaskFilter.h | 42 - libskia/include/effects/SkTableColorFilter.h | 16 +- libskia/include/effects/SkTableMaskFilter.h | 31 +- libskia/include/effects/SkTestImageFilters.h | 27 - libskia/include/effects/SkTileImageFilter.h | 29 +- libskia/include/effects/SkTransparentShader.h | 37 - .../include/effects/SkXfermodeImageFilter.h | 61 +- libskia/include/gpu/GrBackendEffectFactory.h | 90 - libskia/include/gpu/GrBitmapTextContext.h | 46 - libskia/include/gpu/GrBlend.h | 228 + libskia/include/gpu/GrBuffer.h | 136 + libskia/include/gpu/GrCaps.h | 255 + libskia/include/gpu/GrClip.h | 146 + libskia/include/gpu/GrClipData.h | 54 - libskia/include/gpu/GrColor.h | 244 +- libskia/include/gpu/GrColorSpaceXform.h | 45 + libskia/include/gpu/GrConfig.h | 99 +- libskia/include/gpu/GrContext.h | 1142 ++-- libskia/include/gpu/GrContextFactory.h | 172 - libskia/include/gpu/GrContextOptions.h | 90 + libskia/include/gpu/GrCoordTransform.h | 121 +- .../include/gpu/GrDistanceFieldTextContext.h | 55 - libskia/include/gpu/GrDrawEffect.h | 50 - libskia/include/gpu/GrEffect.h | 365 -- libskia/include/gpu/GrEffectStage.h | 223 - libskia/include/gpu/GrEffectUnitTest.h | 101 - libskia/include/gpu/GrFontScaler.h | 38 - libskia/include/gpu/GrFragmentProcessor.h | 269 + libskia/include/gpu/GrGlyph.h | 78 - libskia/include/gpu/GrGpuResource.h | 337 ++ libskia/include/gpu/GrGpuResourceRef.h | 217 + libskia/include/gpu/GrInvariantOutput.h | 342 ++ libskia/include/gpu/GrKey.h | 38 - libskia/include/gpu/GrPaint.h | 271 +- libskia/include/gpu/GrPoint.h | 30 - libskia/include/gpu/GrProcessor.h | 323 ++ libskia/include/gpu/GrProcessorUnitTest.h | 154 + libskia/include/gpu/GrProgramElement.h | 148 + libskia/include/gpu/GrRenderTarget.h | 132 +- libskia/include/gpu/GrRenderTargetContext.h | 471 ++ libskia/include/gpu/GrResource.h | 143 - libskia/include/gpu/GrResourceKey.h | 322 ++ libskia/include/gpu/GrSamplerParams.h | 110 + libskia/include/gpu/GrShaderCaps.h | 344 ++ libskia/include/gpu/GrShaderVar.h | 334 ++ libskia/include/gpu/GrSurface.h | 140 +- libskia/include/gpu/GrSurfaceContext.h | 43 + libskia/include/gpu/GrTBackendEffectFactory.h | 89 - libskia/include/gpu/GrTestUtils.h | 150 + libskia/include/gpu/GrTextContext.h | 40 - libskia/include/gpu/GrTexture.h | 196 +- libskia/include/gpu/GrTextureAccess.h | 188 - libskia/include/gpu/GrTextureContext.h | 53 + libskia/include/gpu/GrTextureProvider.h | 173 + libskia/include/gpu/GrTypes.h | 428 +- libskia/include/gpu/GrTypesPriv.h | 542 +- libskia/include/gpu/GrUserConfig.h | 34 - libskia/include/gpu/GrXferProcessor.h | 384 ++ libskia/include/gpu/SkGpuDevice.h | 219 - libskia/include/gpu/SkGr.h | 131 +- libskia/include/gpu/SkGrPixelRef.h | 66 - libskia/include/gpu/SkGrTexturePixelRef.h | 19 - .../gpu/effects/GrConstColorProcessor.h | 66 + .../include/gpu/effects/GrCoverageSetOpXP.h | 54 + .../include/gpu/effects/GrCustomXfermode.h | 26 + .../gpu/effects/GrPorterDuffXferProcessor.h | 77 + .../gpu/effects/GrXfermodeFragmentProcessor.h | 35 + .../include/gpu/gl/GrGLAssembleInterface.h | 30 + libskia/include/gpu/gl/GrGLConfig.h | 94 +- libskia/include/gpu/gl/GrGLConfig_chrome.h | 18 - libskia/include/gpu/gl/GrGLExtensions.h | 53 +- libskia/include/gpu/gl/GrGLFunctions.h | 580 +- libskia/include/gpu/gl/GrGLInterface.h | 715 +-- libskia/include/gpu/gl/GrGLSLPrettyPrint.h | 19 + libskia/include/gpu/gl/GrGLTypes.h | 117 + libskia/include/gpu/gl/SkANGLEGLContext.h | 50 - libskia/include/gpu/gl/SkDebugGLContext.h | 27 - libskia/include/gpu/gl/SkGLContextHelper.h | 89 - libskia/include/gpu/gl/SkMesaGLContext.h | 51 - libskia/include/gpu/gl/SkNativeGLContext.h | 86 - libskia/include/gpu/gl/SkNullGLContext.h | 28 - libskia/include/gpu/vk/GrVkBackendContext.h | 62 + libskia/include/gpu/vk/GrVkDefines.h | 26 + libskia/include/gpu/vk/GrVkInterface.h | 206 + libskia/include/gpu/vk/GrVkTypes.h | 64 + libskia/include/images/SkForceLinking.h | 15 +- libskia/include/images/SkImageRef.h | 104 - .../include/images/SkImageRef_GlobalPool.h | 62 - libskia/include/images/SkImages.h | 14 - libskia/include/images/SkMovie.h | 80 - libskia/include/images/SkPageFlipper.h | 62 - libskia/include/pathops/SkPathOps.h | 54 +- libskia/include/pdf/SkPDFDevice.h | 342 -- libskia/include/pdf/SkPDFDocument.h | 105 - libskia/include/pipe/SkGPipe.h | 168 - libskia/include/ports/SkFontConfigInterface.h | 40 +- libskia/include/ports/SkFontMgr.h | 150 +- .../ports/SkFontMgr_FontConfigInterface.h | 20 + libskia/include/ports/SkFontMgr_android.h | 52 + libskia/include/ports/SkFontMgr_custom.h | 21 + libskia/include/ports/SkFontMgr_fontconfig.h | 22 + libskia/include/ports/SkFontMgr_indirect.h | 105 + libskia/include/ports/SkHarfBuzzFont.h | 42 - libskia/include/ports/SkRemotableFontMgr.h | 148 + libskia/include/ports/SkTypeface_android.h | 110 - libskia/include/ports/SkTypeface_mac.h | 30 +- libskia/include/ports/SkTypeface_win.h | 33 +- libskia/include/private/GrAuditTrail.h | 189 + .../{src/gpu/gl => include/private}/GrGLSL.h | 97 +- .../gpu/gl => include/private}/GrGLSL_impl.h | 0 .../include/private/GrInstancedPipelineInfo.h | 49 + libskia/include/private/GrRenderTargetProxy.h | 82 + libskia/include/private/GrSingleOwner.h | 55 + libskia/include/private/GrSurfaceProxy.h | 319 ++ libskia/include/private/GrSwizzle.h | 115 + libskia/include/private/GrTextureProxy.h | 46 + .../private/GrTextureRenderTargetProxy.h | 41 + .../private}/GrTextureStripAtlas.h | 61 +- libskia/include/private/SkAtomics.h | 159 + libskia/include/private/SkBitmaskEnum.h | 34 + libskia/include/private/SkChecksum.h | 70 + .../include/{core => private}/SkChunkAlloc.h | 25 +- libskia/include/{core => private}/SkFixed.h | 113 +- .../include/{core => private}/SkFloatBits.h | 43 +- libskia/include/private/SkFloatingPoint.h | 156 + libskia/include/private/SkLeanWindows.h | 34 + libskia/include/private/SkMiniRecorder.h | 56 + libskia/include/private/SkMutex.h | 93 + libskia/include/private/SkOnce.h | 50 + libskia/include/private/SkRecords.h | 358 ++ libskia/include/private/SkSafe_math.h | 52 + libskia/include/private/SkSemaphore.h | 83 + libskia/include/private/SkShadowParams.h | 48 + libskia/include/private/SkSpinlock.h | 47 + libskia/include/{core => private}/SkTArray.h | 280 +- libskia/include/{core => private}/SkTDArray.h | 150 +- libskia/include/{core => private}/SkTDict.h | 71 +- libskia/include/private/SkTFitsIn.h | 227 + libskia/include/private/SkTHash.h | 301 ++ libskia/include/private/SkTLogic.h | 104 + libskia/include/{core => private}/SkTSearch.h | 2 +- .../include/{core => private}/SkTemplates.h | 290 +- libskia/include/private/SkThreadID.h | 19 + .../include/{core => private}/SkWeakRefCnt.h | 64 +- libskia/include/svg/SkSVGAttribute.h | 42 - libskia/include/svg/SkSVGBase.h | 25 - libskia/include/svg/SkSVGCanvas.h | 37 + libskia/include/svg/SkSVGPaintState.h | 89 - libskia/include/svg/SkSVGParser.h | 74 - libskia/include/svg/SkSVGTypes.h | 40 - libskia/include/text/SkTextLayout.h | 60 - libskia/include/utils/SkBoundaryPatch.h | 2 +- libskia/include/utils/SkCamera.h | 32 +- libskia/include/utils/SkCanvasStateUtils.h | 29 +- libskia/include/utils/SkCondVar.h | 68 - libskia/include/utils/SkCountdown.h | 36 - libskia/include/utils/SkCubicInterval.h | 22 - libskia/include/utils/SkCullPoints.h | 71 - libskia/include/utils/SkDebugUtils.h | 94 - libskia/include/utils/SkDeferredCanvas.h | 256 - libskia/include/utils/SkDumpCanvas.h | 129 +- libskia/include/utils/SkEventTracer.h | 70 + libskia/include/utils/SkFrontBufferedStream.h | 6 +- libskia/include/utils/SkInterpolator.h | 14 +- libskia/include/utils/SkJSON.h | 285 - libskia/include/utils/SkJSONCPP.h | 26 - libskia/include/utils/SkLayer.h | 4 +- libskia/include/utils/SkLua.h | 12 + libskia/include/utils/SkLuaCanvas.h | 94 +- libskia/include/utils/SkNWayCanvas.h | 114 +- libskia/include/utils/SkNinePatch.h | 33 - libskia/include/utils/SkNoDrawCanvas.h | 32 + libskia/include/utils/SkNullCanvas.h | 8 +- libskia/include/utils/SkPaintFilterCanvas.h | 106 + libskia/include/utils/SkParse.h | 2 +- libskia/include/utils/SkParsePaint.h | 26 - libskia/include/utils/SkPathUtils.h | 40 - libskia/include/utils/SkPictureUtils.h | 19 +- libskia/include/utils/SkProxyCanvas.h | 94 - libskia/include/utils/SkRTConf.h | 193 - libskia/include/utils/SkRandom.h | 185 +- libskia/include/utils/SkRunnable.h | 17 - libskia/include/utils/SkTextBox.h | 87 + libskia/include/utils/SkThreadPool.h | 63 - libskia/include/utils/SkUnitMappers.h | 55 - libskia/include/utils/ios/SkStream_NSData.h | 41 - libskia/include/utils/mac/SkCGUtils.h | 45 +- libskia/include/views/SkApplication.h | 30 + libskia/include/views/SkEvent.h | 293 + libskia/include/views/SkEventSink.h | 112 + libskia/include/views/SkKey.h | 62 + libskia/include/views/SkOSMenu.h | 182 + libskia/include/views/SkOSWindow_Mac.h | 60 + libskia/include/views/SkOSWindow_SDL.h | 54 + libskia/include/views/SkOSWindow_Unix.h | 86 + libskia/include/views/SkOSWindow_Win.h | 135 + libskia/include/views/SkOSWindow_iOS.h | 50 + libskia/include/views/SkSystemEventTypes.h | 25 + libskia/include/views/SkTouchGesture.h | 83 + libskia/include/views/SkView.h | 405 ++ libskia/include/views/SkWindow.h | 139 + libskia/include/xml/SkDOM.h | 99 + libskia/include/xml/SkXMLParser.h | 87 + libskia/include/xml/SkXMLWriter.h | 95 + libskia/libskia.gyp | 1841 ++++++- libskia/rename.sh | 25 + libskia/src/android/SkBitmapRegionCodec.cpp | 142 + libskia/src/android/SkBitmapRegionCodec.h | 37 + libskia/src/android/SkBitmapRegionDecoder.cpp | 47 + .../src/android/SkBitmapRegionDecoderPriv.h | 59 + .../SkADrawable.cpp} | 14 +- libskia/src/animator/SkADrawable.h | 28 + libskia/src/animator/SkAnimate.h | 34 + libskia/src/animator/SkAnimateActive.cpp | 504 ++ libskia/src/animator/SkAnimateActive.h | 79 + libskia/src/animator/SkAnimateBase.cpp | 235 + libskia/src/animator/SkAnimateBase.h | 83 + libskia/src/animator/SkAnimateField.cpp | 111 + libskia/src/animator/SkAnimateMaker.cpp | 372 ++ libskia/src/animator/SkAnimateMaker.h | 160 + libskia/src/animator/SkAnimateProperties.h | 21 + libskia/src/animator/SkAnimateSet.cpp | 87 + libskia/src/animator/SkAnimateSet.h | 27 + libskia/src/animator/SkAnimator.cpp | 704 +++ libskia/src/animator/SkAnimatorScript.cpp | 594 +++ libskia/src/animator/SkAnimatorScript.h | 75 + libskia/src/animator/SkAnimatorScript2.cpp | 622 +++ libskia/src/animator/SkAnimatorScript2.h | 50 + libskia/src/animator/SkBoundable.cpp | 55 + libskia/src/animator/SkBoundable.h | 41 + libskia/src/animator/SkBuildCondensedInfo.cpp | 282 + libskia/src/animator/SkDisplayAdd.cpp | 245 + libskia/src/animator/SkDisplayAdd.h | 71 + libskia/src/animator/SkDisplayApply.cpp | 804 +++ libskia/src/animator/SkDisplayApply.h | 106 + libskia/src/animator/SkDisplayBounds.cpp | 43 + libskia/src/animator/SkDisplayBounds.h | 24 + libskia/src/animator/SkDisplayEvent.cpp | 252 + libskia/src/animator/SkDisplayEvent.h | 66 + libskia/src/animator/SkDisplayEvents.cpp | 113 + libskia/src/animator/SkDisplayEvents.h | 42 + libskia/src/animator/SkDisplayInclude.cpp | 52 + libskia/src/animator/SkDisplayInclude.h | 25 + libskia/src/animator/SkDisplayInput.cpp | 55 + libskia/src/animator/SkDisplayInput.h | 33 + libskia/src/animator/SkDisplayList.cpp | 158 + libskia/src/animator/SkDisplayList.h | 68 + libskia/src/animator/SkDisplayMath.cpp | 229 + libskia/src/animator/SkDisplayMath.h | 31 + libskia/src/animator/SkDisplayMovie.cpp | 128 + libskia/src/animator/SkDisplayMovie.h | 51 + libskia/src/animator/SkDisplayNumber.cpp | 70 + libskia/src/animator/SkDisplayNumber.h | 22 + libskia/src/animator/SkDisplayPost.cpp | 298 ++ libskia/src/animator/SkDisplayPost.h | 59 + libskia/src/animator/SkDisplayRandom.cpp | 65 + libskia/src/animator/SkDisplayRandom.h | 40 + libskia/src/animator/SkDisplayScreenplay.cpp | 20 + libskia/src/animator/SkDisplayScreenplay.h | 21 + libskia/src/animator/SkDisplayType.cpp | 761 +++ libskia/src/animator/SkDisplayType.h | 206 + libskia/src/animator/SkDisplayTypes.cpp | 214 + libskia/src/animator/SkDisplayTypes.h | 104 + libskia/src/animator/SkDisplayXMLParser.cpp | 316 ++ libskia/src/animator/SkDisplayXMLParser.h | 91 + libskia/src/animator/SkDisplayable.cpp | 540 ++ libskia/src/animator/SkDisplayable.h | 112 + libskia/src/animator/SkDraw3D.cpp | 106 + libskia/src/animator/SkDraw3D.h | 50 + libskia/src/animator/SkDrawBitmap.cpp | 201 + libskia/src/animator/SkDrawBitmap.h | 73 + libskia/src/animator/SkDrawBlur.cpp | 33 + libskia/src/animator/SkDrawBlur.h | 25 + libskia/src/animator/SkDrawClip.cpp | 39 + libskia/src/animator/SkDrawClip.h | 29 + libskia/src/animator/SkDrawColor.cpp | 265 + libskia/src/animator/SkDrawColor.h | 40 + libskia/src/animator/SkDrawDash.cpp | 35 + libskia/src/animator/SkDrawDash.h | 24 + libskia/src/animator/SkDrawDiscrete.cpp | 34 + libskia/src/animator/SkDrawDiscrete.h | 22 + libskia/src/animator/SkDrawEmboss.cpp | 34 + libskia/src/animator/SkDrawEmboss.h | 28 + .../src/animator/SkDrawExtraPathEffect.cpp | 522 ++ .../animator}/SkDrawExtraPathEffect.h | 0 libskia/src/animator/SkDrawFull.cpp | 18 + libskia/src/animator/SkDrawFull.h | 22 + libskia/src/animator/SkDrawGradient.cpp | 168 + libskia/src/animator/SkDrawGradient.h | 64 + libskia/src/animator/SkDrawGroup.cpp | 321 ++ libskia/src/animator/SkDrawGroup.h | 72 + libskia/src/animator/SkDrawLine.cpp | 35 + libskia/src/animator/SkDrawLine.h | 28 + libskia/src/animator/SkDrawMatrix.cpp | 268 + libskia/src/animator/SkDrawMatrix.h | 74 + libskia/src/animator/SkDrawOval.cpp | 28 + libskia/src/animator/SkDrawOval.h | 22 + libskia/src/animator/SkDrawPaint.cpp | 267 + libskia/src/animator/SkDrawPaint.h | 78 + libskia/src/animator/SkDrawPath.cpp | 220 + libskia/src/animator/SkDrawPath.h | 69 + libskia/src/animator/SkDrawPoint.cpp | 44 + libskia/src/animator/SkDrawPoint.h | 33 + libskia/src/animator/SkDrawRectangle.cpp | 142 + libskia/src/animator/SkDrawRectangle.h | 55 + libskia/src/animator/SkDrawSaveLayer.cpp | 76 + libskia/src/animator/SkDrawSaveLayer.h | 36 + libskia/src/animator/SkDrawShader.cpp | 78 + libskia/src/animator/SkDrawShader.h | 28 + libskia/src/animator/SkDrawText.cpp | 55 + libskia/src/animator/SkDrawText.h | 36 + libskia/src/animator/SkDrawTextBox.cpp | 80 + libskia/src/animator/SkDrawTextBox.h | 38 + libskia/src/animator/SkDrawTo.cpp | 55 + libskia/src/animator/SkDrawTo.h | 34 + libskia/src/animator/SkDump.cpp | 150 + libskia/src/animator/SkDump.h | 42 + libskia/src/animator/SkExtras.h | 34 + libskia/src/animator/SkGetCondensedInfo.cpp | 121 + libskia/src/animator/SkHitClear.cpp | 32 + libskia/src/animator/SkHitClear.h | 25 + libskia/src/animator/SkHitTest.cpp | 74 + libskia/src/animator/SkHitTest.h | 30 + libskia/src/animator/SkIntArray.h | 55 + libskia/src/animator/SkMatrixParts.cpp | 292 + libskia/src/animator/SkMatrixParts.h | 119 + libskia/src/animator/SkMemberInfo.cpp | 559 ++ libskia/src/animator/SkMemberInfo.h | 276 + libskia/src/animator/SkOpArray.cpp | 23 + libskia/src/animator/SkOpArray.h | 29 + libskia/src/animator/SkOperand.h | 46 + libskia/src/animator/SkOperand2.h | 54 + libskia/src/animator/SkOperandInterpolator.h | 47 + libskia/src/animator/SkOperandIterpolator.cpp | 147 + libskia/src/animator/SkPaintPart.cpp | 99 + libskia/src/animator/SkPaintPart.h | 71 + libskia/src/animator/SkParseSVGPath.cpp | 234 + libskia/src/animator/SkPathParts.cpp | 318 ++ libskia/src/animator/SkPathParts.h | 164 + libskia/src/animator/SkPostParts.cpp | 56 + libskia/src/animator/SkPostParts.h | 31 + libskia/src/animator/SkScript.cpp | 1890 +++++++ libskia/src/animator/SkScript.h | 264 + libskia/src/animator/SkScript2.h | 293 + libskia/src/animator/SkScriptCallBack.h | 67 + libskia/src/animator/SkScriptDecompile.cpp | 211 + libskia/src/animator/SkScriptRuntime.cpp | 351 ++ libskia/src/animator/SkScriptRuntime.h | 50 + libskia/src/animator/SkScriptTokenizer.cpp | 1506 ++++++ libskia/src/animator/SkSnapshot.cpp | 67 + libskia/src/animator/SkSnapshot.h | 29 + libskia/src/animator/SkTDArray_Experimental.h | 142 + .../core => src/animator}/SkTDStack.h | 0 libskia/src/animator/SkTextOnPath.cpp | 39 + libskia/src/animator/SkTextOnPath.h | 30 + libskia/src/animator/SkTextToPath.cpp | 47 + libskia/src/animator/SkTextToPath.h | 31 + libskia/src/animator/SkTypedArray.cpp | 179 + libskia/src/animator/SkTypedArray.h | 31 + libskia/src/animator/SkXMLAnimatorWriter.cpp | 84 + libskia/src/animator/SkXMLAnimatorWriter.h | 36 + libskia/src/c/sk_c_from_to.h | 34 + libskia/src/c/sk_paint.cpp | 173 + libskia/src/c/sk_surface.cpp | 707 +++ libskia/src/c/sk_types_priv.h | 41 + libskia/src/codec/SkAndroidCodec.cpp | 195 + libskia/src/codec/SkBmpCodec.cpp | 646 +++ libskia/src/codec/SkBmpCodec.h | 162 + libskia/src/codec/SkBmpMaskCodec.cpp | 108 + libskia/src/codec/SkBmpMaskCodec.h | 60 + libskia/src/codec/SkBmpRLECodec.cpp | 595 +++ libskia/src/codec/SkBmpRLECodec.h | 117 + libskia/src/codec/SkBmpStandardCodec.cpp | 353 ++ libskia/src/codec/SkBmpStandardCodec.h | 100 + libskia/src/codec/SkCodec.cpp | 485 ++ libskia/src/codec/SkCodecAnimation.h | 50 + libskia/src/codec/SkCodecImageGenerator.cpp | 65 + libskia/src/codec/SkCodecImageGenerator.h | 43 + libskia/src/codec/SkCodecPriv.h | 382 ++ libskia/src/codec/SkGifCodec.cpp | 628 +++ libskia/src/codec/SkGifCodec.h | 154 + libskia/src/codec/SkIcoCodec.cpp | 392 ++ libskia/src/codec/SkIcoCodec.h | 101 + libskia/src/codec/SkJpegCodec.cpp | 933 ++++ libskia/src/codec/SkJpegCodec.h | 140 + libskia/src/codec/SkJpegDecoderMgr.cpp | 101 + libskia/src/codec/SkJpegDecoderMgr.h | 75 + libskia/src/codec/SkJpegUtility.cpp | 95 + libskia/src/codec/SkJpegUtility.h | 50 + libskia/src/codec/SkMaskSwizzler.cpp | 568 ++ libskia/src/codec/SkMaskSwizzler.h | 78 + libskia/src/codec/SkMasks.cpp | 161 + libskia/src/codec/SkMasks.h | 86 + libskia/src/codec/SkPngCodec.cpp | 1257 +++++ libskia/src/codec/SkPngCodec.h | 140 + libskia/src/codec/SkRawAdapterCodec.cpp | 30 + libskia/src/codec/SkRawAdapterCodec.h | 42 + libskia/src/codec/SkRawCodec.cpp | 803 +++ libskia/src/codec/SkRawCodec.h | 61 + libskia/src/codec/SkSampledCodec.cpp | 349 ++ libskia/src/codec/SkSampledCodec.h | 60 + libskia/src/codec/SkSampler.cpp | 96 + libskia/src/codec/SkSampler.h | 93 + libskia/src/codec/SkStreamBuffer.cpp | 23 + libskia/src/codec/SkStreamBuffer.h | 68 + libskia/src/codec/SkSwizzler.cpp | 1078 ++++ libskia/src/codec/SkSwizzler.h | 216 + libskia/src/codec/SkWbmpCodec.cpp | 219 + libskia/src/codec/SkWbmpCodec.h | 64 + libskia/src/codec/SkWebpAdapterCodec.cpp | 45 + libskia/src/codec/SkWebpAdapterCodec.h | 37 + libskia/src/codec/SkWebpCodec.cpp | 333 ++ libskia/src/codec/SkWebpCodec.h | 52 + .../core/ARGB32_Clamp_Bilinear_BitmapShader.h | 177 - libskia/src/core/Sk4px.h | 241 + libskia/src/core/Sk4x4f.h | 157 + libskia/src/core/Sk64.cpp | 286 - libskia/src/core/SkAAClip.cpp | 222 +- libskia/src/core/SkAAClip.h | 30 +- libskia/src/core/SkATrace.cpp | 69 + libskia/src/core/SkATrace.h | 54 + .../src/core/SkAdvancedTypefaceMetrics.cpp | 317 -- libskia/src/core/SkAdvancedTypefaceMetrics.h | 103 + libskia/src/core/SkAlphaRuns.cpp | 1 - libskia/src/core/SkAnalyticEdge.cpp | 234 + libskia/src/core/SkAnalyticEdge.h | 150 + libskia/src/core/SkAnnotation.cpp | 60 +- libskia/src/core/SkAnnotationKeys.h | 33 + libskia/src/core/SkAntiRun.h | 10 +- libskia/src/core/SkAutoKern.h | 14 +- libskia/src/core/SkAutoPixmapStorage.cpp | 58 + libskia/src/core/SkAutoPixmapStorage.h | 78 + libskia/src/core/SkBBHFactory.cpp | 16 + libskia/src/core/SkBBoxHierarchy.h | 69 +- libskia/src/core/SkBBoxHierarchyRecord.cpp | 115 - libskia/src/core/SkBBoxHierarchyRecord.h | 58 - libskia/src/core/SkBBoxRecord.cpp | 295 -- libskia/src/core/SkBBoxRecord.h | 79 - libskia/src/core/SkBigPicture.cpp | 94 + libskia/src/core/SkBigPicture.h | 84 + libskia/src/core/SkBitmap.cpp | 1803 +++---- libskia/src/core/SkBitmapCache.cpp | 290 + libskia/src/core/SkBitmapCache.h | 81 + libskia/src/core/SkBitmapController.cpp | 258 + libskia/src/core/SkBitmapController.h | 70 + libskia/src/core/SkBitmapDevice.cpp | 442 +- libskia/src/core/SkBitmapFilter.cpp | 148 - libskia/src/core/SkBitmapFilter.h | 282 +- libskia/src/core/SkBitmapHeap.cpp | 399 -- libskia/src/core/SkBitmapHeap.h | 307 -- libskia/src/core/SkBitmapProcShader.cpp | 583 +- libskia/src/core/SkBitmapProcShader.h | 41 +- libskia/src/core/SkBitmapProcState.cpp | 799 +-- libskia/src/core/SkBitmapProcState.h | 194 +- libskia/src/core/SkBitmapProcState_filter.h | 9 +- libskia/src/core/SkBitmapProcState_matrix.h | 168 +- .../core/SkBitmapProcState_matrixProcs.cpp | 178 +- .../core/SkBitmapProcState_matrix_template.h | 118 + libskia/src/core/SkBitmapProcState_procs.h | 142 +- libskia/src/core/SkBitmapProcState_sample.h | 92 +- .../src/core/SkBitmapProcState_shaderproc.h | 29 +- libskia/src/core/SkBitmapProvider.cpp | 84 + libskia/src/core/SkBitmapProvider.h | 56 + libskia/src/core/SkBitmapScaler.cpp | 366 +- libskia/src/core/SkBitmapScaler.h | 90 +- .../src/core/SkBitmapShader16BilerpTemplate.h | 245 - libskia/src/core/SkBitmapShaderTemplate.h | 306 -- libskia/src/core/SkBitmap_scroll.cpp | 123 - libskia/src/core/SkBlendModePriv.h | 24 + libskia/src/core/SkBlitBWMaskTemplate.h | 11 +- libskia/src/core/SkBlitMask.h | 28 +- libskia/src/core/SkBlitMask_D32.cpp | 381 +- libskia/src/core/SkBlitRow_D16.cpp | 72 +- libskia/src/core/SkBlitRow_D32.cpp | 170 +- libskia/src/core/SkBlitter.cpp | 758 +-- libskia/src/core/SkBlitter.h | 218 +- libskia/src/core/SkBlitter_A8.cpp | 91 +- libskia/src/core/SkBlitter_ARGB32.cpp | 233 +- libskia/src/core/SkBlitter_PM4f.cpp | 436 ++ libskia/src/core/SkBlitter_RGB16.cpp | 423 +- libskia/src/core/SkBlitter_Sprite.cpp | 178 +- libskia/src/core/SkBlurImageFilter.cpp | 296 ++ libskia/src/core/SkBuffer.cpp | 12 +- libskia/src/core/SkBuffer.h | 4 +- libskia/src/core/SkCachedData.cpp | 198 + libskia/src/core/SkCachedData.h | 112 + libskia/src/core/SkCanvas.cpp | 3365 ++++++++---- libskia/src/core/SkCanvasPriv.h | 23 + libskia/src/core/SkChunkAlloc.cpp | 137 +- libskia/src/core/SkClipStack.cpp | 595 ++- libskia/src/core/SkColor.cpp | 98 +- libskia/src/core/SkColorFilter.cpp | 180 +- libskia/src/core/SkColorFilterShader.cpp | 141 + libskia/src/core/SkColorFilterShader.h | 59 + libskia/src/core/SkColorLookUpTable.cpp | 162 + libskia/src/core/SkColorLookUpTable.h | 66 + .../core/SkColorMatrixFilterRowMajor255.cpp | 469 ++ .../src/core/SkColorMatrixFilterRowMajor255.h | 51 + libskia/src/core/SkColorShader.cpp | 331 ++ libskia/src/core/SkColorShader.h | 135 + libskia/src/core/SkColorSpace.cpp | 528 ++ libskia/src/core/SkColorSpacePriv.h | 86 + libskia/src/core/SkColorSpaceXform.cpp | 1455 +++++ libskia/src/core/SkColorSpaceXformPriv.h | 84 + libskia/src/core/SkColorSpaceXform_A2B.cpp | 354 ++ libskia/src/core/SkColorSpaceXform_A2B.h | 59 + libskia/src/core/SkColorSpaceXform_Base.h | 118 + libskia/src/core/SkColorSpace_A2B.cpp | 16 + libskia/src/core/SkColorSpace_A2B.h | 181 + libskia/src/core/SkColorSpace_Base.h | 224 + libskia/src/core/SkColorSpace_ICC.cpp | 1770 +++++++ libskia/src/core/SkColorSpace_XYZ.cpp | 96 + libskia/src/core/SkColorSpace_XYZ.h | 61 + libskia/src/core/SkColorTable.cpp | 115 +- libskia/src/core/SkComposeShader.cpp | 214 +- libskia/src/core/SkComposeShader.h | 86 + libskia/src/core/SkConfig8888.cpp | 648 ++- libskia/src/core/SkConfig8888.h | 90 +- libskia/src/core/SkConvolver.cpp | 259 +- libskia/src/core/SkConvolver.h | 70 +- libskia/src/core/SkCordic.cpp | 289 - libskia/src/core/SkCordic.h | 28 - libskia/src/core/SkCoreBlitters.h | 129 +- libskia/src/core/SkCpu.cpp | 101 + libskia/src/core/SkCpu.h | 96 + libskia/src/core/SkCubicClipper.cpp | 7 +- libskia/src/core/SkCubicClipper.h | 4 +- libskia/src/core/SkData.cpp | 134 +- libskia/src/core/SkDataTable.cpp | 71 +- libskia/src/core/SkDebug.cpp | 36 +- libskia/src/core/SkDeduper.h | 39 + libskia/src/core/SkDeque.cpp | 93 +- libskia/src/core/SkDescriptor.h | 60 +- libskia/src/core/SkDevice.cpp | 671 ++- libskia/src/core/SkDeviceImageFilterProxy.h | 34 - libskia/src/core/SkDeviceLooper.cpp | 38 +- libskia/src/core/SkDeviceLooper.h | 15 +- libskia/src/core/SkDeviceProfile.cpp | 8 +- libskia/src/core/SkDeviceProfile.h | 6 +- libskia/src/core/SkDiscardableMemory.h | 4 +- libskia/src/core/SkDistanceFieldGen.cpp | 521 ++ libskia/src/core/SkDistanceFieldGen.h | 62 + libskia/src/core/SkDither.cpp | 1 - libskia/{include => src}/core/SkDither.h | 1 - libskia/src/core/SkDocument.cpp | 95 + libskia/src/core/SkDraw.cpp | 1929 +++---- libskia/src/core/SkDrawLooper.cpp | 36 +- libskia/src/core/SkDrawProcs.h | 76 +- libskia/src/core/SkDrawable.cpp | 85 + libskia/src/core/SkEdge.cpp | 85 +- libskia/src/core/SkEdge.h | 20 +- libskia/src/core/SkEdgeBuilder.cpp | 296 +- libskia/src/core/SkEdgeBuilder.h | 30 +- libskia/src/core/SkEdgeClipper.cpp | 226 +- libskia/src/core/SkEdgeClipper.h | 6 +- libskia/src/core/SkEmptyShader.h | 47 + libskia/{include => src}/core/SkEndian.h | 21 +- libskia/src/core/SkError.cpp | 143 - libskia/src/core/SkErrorInternals.h | 27 - libskia/src/core/SkExchange.h | 25 + libskia/src/core/SkFDot6.h | 68 +- libskia/src/core/SkFDot6Constants.h | 199 + libskia/src/core/SkFP.h | 79 - libskia/src/core/SkFilterProc.cpp | 1 - libskia/src/core/SkFilterProc.h | 1 - libskia/src/core/SkFilterShader.cpp | 102 - libskia/src/core/SkFilterShader.h | 41 - libskia/src/core/SkFindAndPlaceGlyph.h | 736 +++ libskia/src/core/SkFixed15.h | 71 + libskia/src/core/SkFixedAlloc.cpp | 51 + libskia/src/core/SkFixedAlloc.h | 115 + libskia/src/core/SkFlate.cpp | 140 - libskia/src/core/SkFlattenable.cpp | 36 +- libskia/src/core/SkFlattenableBuffers.cpp | 115 - .../src/core/SkFlattenableSerialization.cpp | 18 +- libskia/src/core/SkFloat.cpp | 393 -- libskia/src/core/SkFloat.h | 107 - libskia/src/core/SkFloatBits.cpp | 206 - libskia/src/core/SkFont.cpp | 151 + libskia/src/core/SkFontDescriptor.cpp | 112 +- libskia/src/core/SkFontDescriptor.h | 65 +- libskia/src/core/SkFontHost.cpp | 250 - libskia/src/core/SkFontLCDConfig.cpp | 27 + libskia/src/core/SkFontMgr.cpp | 295 ++ libskia/src/core/SkFontStream.cpp | 2 +- libskia/src/core/SkFontStream.h | 2 +- libskia/src/core/SkFontStyle.cpp | 32 + libskia/src/core/SkForceCPlusPlusLinking.cpp | 20 + libskia/src/core/SkFuzzLogging.h | 23 + libskia/src/core/SkGeometry.cpp | 1384 +++-- libskia/{include => src}/core/SkGeometry.h | 252 +- .../src/core/SkGlobalInitialization_core.cpp | 63 + libskia/src/core/SkGlyph.h | 222 +- libskia/src/core/SkGlyphCache.cpp | 777 +-- libskia/src/core/SkGlyphCache.h | 303 +- libskia/src/core/SkGlyphCache_Globals.h | 55 +- libskia/src/core/SkGpuBlurUtils.cpp | 395 ++ libskia/src/core/SkGpuBlurUtils.h | 47 + libskia/src/core/SkGraphics.cpp | 107 +- libskia/src/core/SkHalf.cpp | 97 + libskia/src/core/SkHalf.h | 117 + libskia/src/core/SkImageCacherator.cpp | 634 +++ libskia/src/core/SkImageCacherator.h | 147 + libskia/src/core/SkImageFilter.cpp | 549 +- libskia/src/core/SkImageFilterCache.cpp | 134 + libskia/src/core/SkImageFilterCache.h | 64 + libskia/src/core/SkImageFilterUtils.cpp | 60 - libskia/src/core/SkImageGenerator.cpp | 226 + libskia/src/core/SkImageInfo.cpp | 118 +- libskia/src/core/SkImagePriv.h | 104 + libskia/src/core/SkInstCnt.cpp | 12 - libskia/src/core/SkLatticeIter.cpp | 288 + libskia/src/core/SkLatticeIter.h | 62 + libskia/src/core/SkLightingShader.cpp | 513 ++ libskia/src/core/SkLightingShader.h | 39 + libskia/src/core/SkLights.cpp | 88 + libskia/src/core/SkLineClipper.cpp | 40 +- libskia/{include => src}/core/SkLineClipper.h | 6 +- libskia/src/core/SkLinearBitmapPipeline.cpp | 718 +++ libskia/src/core/SkLinearBitmapPipeline.h | 122 + .../src/core/SkLinearBitmapPipeline_core.h | 250 + .../src/core/SkLinearBitmapPipeline_matrix.h | 118 + .../src/core/SkLinearBitmapPipeline_sample.h | 1038 ++++ .../src/core/SkLinearBitmapPipeline_tile.h | 413 ++ libskia/src/core/SkLiteDL.cpp | 816 +++ libskia/src/core/SkLiteDL.h | 109 + libskia/src/core/SkLiteRecorder.cpp | 209 + libskia/src/core/SkLiteRecorder.h | 96 + libskia/src/core/SkLocalMatrixImageFilter.cpp | 63 + libskia/src/core/SkLocalMatrixImageFilter.h | 38 + libskia/src/core/SkLocalMatrixShader.cpp | 85 + libskia/src/core/SkLocalMatrixShader.h | 66 + libskia/src/{utils => core}/SkMD5.cpp | 14 +- libskia/src/core/SkMD5.h | 41 + libskia/src/core/SkMSAN.h | 40 + libskia/src/core/SkMakeUnique.h | 23 + libskia/src/core/SkMallocPixelRef.cpp | 148 +- libskia/src/core/SkMask.cpp | 26 +- libskia/src/core/SkMaskCache.cpp | 190 + libskia/src/core/SkMaskCache.h | 44 + libskia/src/core/SkMaskFilter.cpp | 140 +- libskia/src/core/SkMaskGamma.cpp | 12 +- libskia/src/core/SkMaskGamma.h | 38 +- libskia/src/core/SkMath.cpp | 215 +- libskia/src/core/SkMathPriv.h | 116 +- libskia/src/core/SkMatrix.cpp | 1257 +++-- libskia/src/{utils => core}/SkMatrix44.cpp | 170 +- libskia/src/core/SkMatrixImageFilter.cpp | 148 + libskia/src/core/SkMatrixImageFilter.h | 53 + libskia/src/core/SkMatrixPriv.h | 102 + libskia/src/core/SkMatrixUtils.h | 29 +- libskia/src/core/SkMessageBus.h | 43 +- libskia/src/core/SkMetaData.cpp | 27 +- libskia/src/core/SkMiniRecorder.cpp | 126 + libskia/src/core/SkMipMap.cpp | 692 ++- libskia/src/core/SkMipMap.h | 74 +- libskia/src/core/SkModeColorFilter.cpp | 212 + libskia/src/core/SkModeColorFilter.h | 64 + libskia/src/core/SkMultiPictureDraw.cpp | 109 + libskia/src/core/SkNextID.h | 21 + libskia/src/core/SkNormalBevelSource.cpp | 309 ++ libskia/src/core/SkNormalBevelSource.h | 57 + libskia/src/core/SkNormalFlatSource.cpp | 106 + libskia/src/core/SkNormalFlatSource.h | 48 + libskia/src/core/SkNormalMapSource.cpp | 267 + libskia/src/core/SkNormalMapSource.h | 62 + libskia/src/core/SkNormalSource.cpp | 24 + libskia/src/core/SkNormalSource.h | 127 + libskia/src/core/SkNormalSourcePriv.h | 57 + libskia/src/core/SkNx.h | 366 ++ libskia/src/core/SkOnce.h | 156 - libskia/src/core/SkOpts.cpp | 130 + libskia/src/core/SkOpts.h | 92 + libskia/src/core/SkOrderedReadBuffer.cpp | 321 -- libskia/src/core/SkOrderedReadBuffer.h | 139 +- libskia/src/core/SkOrderedWriteBuffer.cpp | 319 -- libskia/src/core/SkOrderedWriteBuffer.h | 117 - libskia/src/core/SkOverdrawCanvas.cpp | 306 ++ libskia/src/core/SkOverdrawCanvas.h | 70 + libskia/src/core/SkPM4f.h | 74 + libskia/src/core/SkPM4fPriv.h | 166 + libskia/src/core/SkPackBits.cpp | 411 -- libskia/src/core/SkPaint.cpp | 1973 +++---- libskia/src/core/SkPaintOptionsAndroid.cpp | 40 - libskia/src/core/SkPaintPriv.cpp | 94 +- libskia/src/core/SkPaintPriv.h | 47 +- libskia/src/core/SkPath.cpp | 2150 +++++--- libskia/src/core/SkPathEffect.cpp | 81 +- libskia/src/core/SkPathHeap.cpp | 61 - libskia/src/core/SkPathHeap.h | 50 - libskia/src/core/SkPathMeasure.cpp | 373 +- libskia/src/core/SkPathMeasurePriv.h | 29 + libskia/src/core/SkPathPriv.h | 126 + libskia/src/core/SkPathRef.cpp | 418 +- libskia/src/core/SkPerspIter.h | 2 +- libskia/src/core/SkPicture.cpp | 486 +- libskia/src/core/SkPictureAnalyzer.cpp | 65 + libskia/src/core/SkPictureCommon.h | 140 + libskia/src/core/SkPictureContentInfo.cpp | 175 + libskia/src/core/SkPictureContentInfo.h | 89 + libskia/src/core/SkPictureData.cpp | 658 +++ libskia/src/core/SkPictureData.h | 206 + libskia/src/core/SkPictureFlat.cpp | 50 +- libskia/src/core/SkPictureFlat.h | 644 +-- libskia/src/core/SkPictureImageGenerator.cpp | 159 + libskia/src/core/SkPicturePlayback.cpp | 2281 +++----- libskia/src/core/SkPicturePlayback.h | 246 +- libskia/src/core/SkPictureRecord.cpp | 1743 +++--- libskia/src/core/SkPictureRecord.h | 321 +- libskia/src/core/SkPictureRecorder.cpp | 144 + libskia/src/core/SkPictureShader.cpp | 334 ++ libskia/src/core/SkPictureShader.h | 76 + libskia/src/core/SkPictureStateTree.cpp | 186 - libskia/src/core/SkPictureStateTree.h | 148 - libskia/src/core/SkPipe.h | 104 + libskia/src/core/SkPixelRef.cpp | 390 +- libskia/src/core/SkPixmap.cpp | 329 ++ libskia/src/core/SkPoint.cpp | 45 +- libskia/src/core/SkPoint3.cpp | 80 + libskia/src/core/SkProcSpriteBlitter.cpp | 47 - libskia/src/core/SkPtrRecorder.cpp | 5 +- libskia/src/core/SkPtrRecorder.h | 32 +- libskia/src/core/SkQuadClipper.h | 1 - libskia/src/core/SkRRect.cpp | 295 +- libskia/src/core/SkRTree.cpp | 546 +- libskia/src/core/SkRTree.h | 170 +- libskia/src/core/SkRWBuffer.cpp | 360 ++ libskia/src/core/SkRadialShadowMapShader.cpp | 431 ++ libskia/src/core/SkRadialShadowMapShader.h | 31 + libskia/src/core/SkRasterClip.cpp | 240 +- libskia/src/core/SkRasterClip.h | 54 +- libskia/src/core/SkRasterPipeline.cpp | 50 + libskia/src/core/SkRasterPipeline.h | 127 + libskia/src/core/SkRasterPipelineBlitter.cpp | 333 ++ libskia/src/core/SkRasterizer.cpp | 10 +- libskia/src/core/SkReadBuffer.cpp | 394 ++ libskia/src/core/SkReadBuffer.h | 276 + libskia/{include => src}/core/SkReader32.h | 36 +- libskia/src/core/SkRecord.cpp | 42 + libskia/src/core/SkRecord.h | 198 + libskia/src/core/SkRecordDraw.cpp | 633 +++ libskia/src/core/SkRecordDraw.h | 82 + libskia/src/core/SkRecordOpts.cpp | 308 ++ libskia/src/core/SkRecordOpts.h | 30 + libskia/src/core/SkRecordPattern.h | 175 + libskia/src/core/SkRecordedDrawable.cpp | 94 + libskia/src/core/SkRecordedDrawable.h | 41 + libskia/src/core/SkRecorder.cpp | 432 ++ libskia/src/core/SkRecorder.h | 181 + libskia/src/core/SkRecords.cpp | 23 + libskia/src/core/SkRect.cpp | 180 +- libskia/src/core/SkRefDict.cpp | 15 +- libskia/src/core/SkRefDict.h | 9 +- libskia/src/core/SkRegion.cpp | 51 +- libskia/src/core/SkRegionPriv.h | 14 +- libskia/src/core/SkRegion_path.cpp | 102 +- libskia/src/core/SkRegion_rects.cpp | 290 - libskia/src/core/SkResourceCache.cpp | 699 +++ libskia/src/core/SkResourceCache.h | 290 + libskia/src/core/SkSRGB.cpp | 75 + libskia/src/core/SkSRGB.h | 108 + libskia/src/core/SkScalar.cpp | 7 +- libskia/src/core/SkScaleToSides.h | 68 + libskia/src/core/SkScaledImageCache.cpp | 803 --- libskia/src/core/SkScaledImageCache.h | 203 - libskia/src/core/SkScalerContext.cpp | 547 +- libskia/src/core/SkScalerContext.h | 208 +- libskia/src/core/SkScan.cpp | 7 +- libskia/src/core/SkScan.h | 35 +- libskia/src/core/SkScanPriv.h | 13 +- libskia/src/core/SkScan_AAAPath.cpp | 1389 +++++ libskia/src/core/SkScan_AntiPath.cpp | 174 +- libskia/src/core/SkScan_Antihair.cpp | 324 +- libskia/src/core/SkScan_Hairline.cpp | 590 ++- libskia/src/core/SkScan_Path.cpp | 268 +- libskia/src/core/SkSemaphore.cpp | 73 + libskia/src/core/SkShader.cpp | 341 +- libskia/src/core/SkShadowShader.cpp | 958 ++++ libskia/src/core/SkShadowShader.h | 40 + libskia/src/core/SkSharedMutex.cpp | 354 ++ libskia/src/core/SkSharedMutex.h | 82 + libskia/src/core/SkSinTable.h | 277 - libskia/src/core/SkSinglyLinkedList.h | 97 + libskia/src/core/SkSmallAllocator.h | 152 + libskia/src/core/SkSpanProcs.cpp | 95 + libskia/src/core/SkSpanProcs.h | 24 + libskia/src/core/SkSpecialImage.cpp | 558 ++ libskia/src/core/SkSpecialImage.h | 170 + libskia/src/core/SkSpecialSurface.cpp | 178 + libskia/src/core/SkSpecialSurface.h | 94 + libskia/src/core/SkSpinlock.cpp | 15 + libskia/src/core/SkSpriteBlitter.h | 49 +- libskia/src/core/SkSpriteBlitter4f.cpp | 129 + libskia/src/core/SkSpriteBlitterTemplate.h | 24 +- libskia/src/core/SkSpriteBlitter_ARGB32.cpp | 141 +- libskia/src/core/SkSpriteBlitter_RGB16.cpp | 172 +- libskia/src/core/SkStream.cpp | 383 +- libskia/src/core/SkStreamPriv.h | 36 + libskia/src/core/SkString.cpp | 242 +- libskia/src/core/SkStringUtils.cpp | 44 + libskia/{include => src}/core/SkStringUtils.h | 18 + libskia/src/core/SkStroke.cpp | 1312 ++++- libskia/src/core/SkStroke.h | 22 + libskia/src/core/SkStrokeRec.cpp | 71 +- libskia/src/core/SkStrokerPriv.cpp | 38 +- libskia/src/core/SkStrokerPriv.h | 1 - libskia/src/core/SkSurfacePriv.h | 25 + libskia/src/core/SkSwizzle.cpp | 14 + libskia/src/core/SkTDPQueue.h | 195 + libskia/src/core/SkTDynamicHash.h | 222 +- .../{include => src}/core/SkTInternalLList.h | 20 +- libskia/src/core/SkTLList.h | 223 +- libskia/src/core/SkTLS.cpp | 33 +- libskia/src/core/SkTLS.h | 19 +- libskia/src/core/SkTMultiMap.h | 167 + libskia/src/core/SkTRefArray.h | 112 - libskia/src/core/SkTSearch.cpp | 3 +- libskia/src/core/SkTSort.h | 16 +- libskia/src/core/SkTTopoSort.h | 112 + libskia/src/core/SkTaskGroup.cpp | 210 + libskia/src/core/SkTaskGroup.h | 42 + libskia/src/core/SkTemplatesPriv.h | 76 - libskia/src/core/SkTextBlob.cpp | 779 +++ libskia/src/core/SkTextBlobRunIterator.h | 44 + libskia/src/core/SkTextFormatParams.h | 11 +- libskia/src/core/SkTextMapStateProc.h | 77 + libskia/src/core/SkTextToPathIter.h | 90 +- libskia/src/core/SkThreadID.cpp | 16 + libskia/src/core/SkTileGrid.cpp | 133 - libskia/src/core/SkTileGrid.h | 140 - libskia/src/core/SkTileGridPicture.cpp | 28 - libskia/src/core/SkTime.cpp | 71 + libskia/src/core/SkTraceEvent.h | 534 ++ libskia/src/core/SkTraceEventCommon.h | 1039 ++++ libskia/src/core/SkTypeface.cpp | 331 +- libskia/src/core/SkTypefaceCache.cpp | 106 +- libskia/src/core/SkTypefaceCache.h | 38 +- libskia/src/core/SkTypefacePriv.h | 10 +- libskia/src/core/SkUnPreMultiply.cpp | 10 +- libskia/src/core/SkUtils.cpp | 142 +- libskia/{include => src}/core/SkUtils.h | 54 +- libskia/src/core/SkUtilsArm.cpp | 191 +- libskia/src/core/SkUtilsArm.h | 76 +- libskia/src/core/SkValidatingReadBuffer.cpp | 145 +- libskia/src/core/SkValidatingReadBuffer.h | 75 +- libskia/src/core/SkValidationUtils.h | 14 +- libskia/src/core/SkVarAlloc.cpp | 56 + libskia/src/core/SkVarAlloc.h | 55 + libskia/src/core/SkVertState.cpp | 106 + libskia/src/core/SkVertState.h | 58 + libskia/src/core/SkWriteBuffer.cpp | 286 + libskia/src/core/SkWriter32.cpp | 273 +- libskia/src/core/SkXfermode.cpp | 1709 +++--- libskia/src/core/SkXfermode4f.cpp | 461 ++ libskia/src/core/SkXfermodeF16.cpp | 164 + libskia/src/core/SkXfermodeInterpretation.cpp | 44 + libskia/src/core/SkXfermodeInterpretation.h | 30 + libskia/src/core/SkXfermodePriv.h | 305 ++ libskia/src/core/SkXfermode_proccoeff.h | 55 +- libskia/src/core/SkYUVPlanesCache.cpp | 89 + libskia/src/core/SkYUVPlanesCache.h | 45 + .../GrAlphaThresholdFragmentProcessor.cpp | 199 + .../GrAlphaThresholdFragmentProcessor.h | 68 + .../effects/GrCircleBlurFragmentProcessor.cpp | 358 ++ .../effects/GrCircleBlurFragmentProcessor.h | 75 + libskia/src/effects/Sk1DPathEffect.cpp | 106 +- libskia/src/effects/Sk2DPathEffect.cpp | 63 +- .../src/effects/SkAlphaThresholdFilter.cpp | 273 + libskia/src/effects/SkArcToPathEffect.cpp | 78 + libskia/src/effects/SkArithmeticMode.cpp | 426 +- libskia/src/effects/SkArithmeticModePriv.h | 38 + libskia/src/effects/SkArithmeticMode_gpu.cpp | 297 ++ libskia/src/effects/SkArithmeticMode_gpu.h | 120 + libskia/src/effects/SkAvoidXfermode.cpp | 179 - libskia/src/effects/SkBicubicImageFilter.cpp | 205 - libskia/src/effects/SkBitmapSource.cpp | 80 - libskia/src/effects/SkBlurDrawLooper.cpp | 134 +- libskia/src/effects/SkBlurImageFilter.cpp | 252 - libskia/src/effects/SkBlurMask.cpp | 172 +- libskia/src/effects/SkBlurMask.h | 105 +- libskia/src/effects/SkBlurMaskFilter.cpp | 1312 ++++- libskia/src/effects/SkColorCubeFilter.cpp | 329 ++ .../src/effects/SkColorFilterImageFilter.cpp | 206 +- libskia/src/effects/SkColorFilters.cpp | 850 --- libskia/src/effects/SkColorMatrix.cpp | 137 +- libskia/src/effects/SkColorMatrixFilter.cpp | 502 +- libskia/src/effects/SkComposeImageFilter.cpp | 99 +- libskia/src/effects/SkCornerPathEffect.cpp | 44 +- libskia/src/effects/SkDashPathEffect.cpp | 441 +- libskia/src/effects/SkDiscretePathEffect.cpp | 100 +- .../src/effects/SkDisplacementMapEffect.cpp | 690 +-- .../src/effects/SkDropShadowImageFilter.cpp | 181 +- libskia/src/effects/SkEmbossMask.cpp | 2 +- libskia/src/effects/SkEmbossMask.h | 1 - libskia/src/effects/SkEmbossMaskFilter.cpp | 81 +- libskia/src/effects/SkEmbossMask_Table.h | 1 - libskia/src/effects/SkGammaColorFilter.cpp | 57 + libskia/src/effects/SkGaussianEdgeShader.cpp | 168 + libskia/src/effects/SkGpuBlurUtils.cpp | 265 - libskia/src/effects/SkGpuBlurUtils.h | 46 - libskia/src/effects/SkImageSource.cpp | 143 + libskia/src/effects/SkKernel33MaskFilter.cpp | 142 - libskia/src/effects/SkLayerDrawLooper.cpp | 298 +- libskia/src/effects/SkLayerRasterizer.cpp | 125 +- libskia/src/effects/SkLerpXfermode.cpp | 110 - libskia/src/effects/SkLightingImageFilter.cpp | 2034 ++++--- libskia/src/effects/SkLumaColorFilter.cpp | 115 +- .../src/effects/SkMagnifierImageFilter.cpp | 482 +- .../SkMatrixConvolutionImageFilter.cpp | 685 +-- libskia/src/effects/SkMergeImageFilter.cpp | 216 +- .../src/effects/SkMorphologyImageFilter.cpp | 922 ++-- libskia/src/effects/SkOffsetImageFilter.cpp | 133 +- libskia/src/effects/SkOverdrawColorFilter.cpp | 181 + libskia/src/effects/SkOverdrawColorFilter.h | 54 + libskia/src/effects/SkPackBits.cpp | 107 + libskia/src/effects/SkPackBits.h | 45 + libskia/src/effects/SkPaintImageFilter.cpp | 81 + libskia/src/effects/SkPerlinNoiseShader.cpp | 1174 ++-- libskia/src/effects/SkPictureImageFilter.cpp | 224 +- libskia/src/effects/SkPixelXorXfermode.cpp | 38 - libskia/src/effects/SkPorterDuff.cpp | 87 - .../SkRRectsGaussianEdgeMaskFilter.cpp | 579 ++ .../src/effects/SkRectShaderImageFilter.cpp | 80 - libskia/src/effects/SkShadowMaskFilter.cpp | 408 ++ libskia/src/effects/SkStippleMaskFilter.cpp | 52 - libskia/src/effects/SkTableColorFilter.cpp | 484 +- libskia/src/effects/SkTableMaskFilter.cpp | 26 +- libskia/src/effects/SkTestImageFilters.cpp | 83 - libskia/src/effects/SkTileImageFilter.cpp | 178 +- libskia/src/effects/SkTransparentShader.cpp | 119 - libskia/src/effects/SkXfermodeImageFilter.cpp | 589 ++- .../effects/gradients/Sk4fGradientBase.cpp | 459 ++ .../src/effects/gradients/Sk4fGradientBase.h | 75 + .../src/effects/gradients/Sk4fGradientPriv.h | 194 + .../effects/gradients/Sk4fLinearGradient.cpp | 533 ++ .../effects/gradients/Sk4fLinearGradient.h | 51 + .../src/effects/gradients/SkClampRange.cpp | 105 +- libskia/src/effects/gradients/SkClampRange.h | 27 +- ...mapCache.cpp => SkGradientBitmapCache.cpp} | 41 +- ...kBitmapCache.h => SkGradientBitmapCache.h} | 17 +- .../effects/gradients/SkGradientShader.cpp | 1966 ++++--- .../effects/gradients/SkGradientShaderPriv.h | 449 +- .../effects/gradients/SkLinearGradient.cpp | 837 +-- .../src/effects/gradients/SkLinearGradient.h | 63 +- .../effects/gradients/SkRadialGradient.cpp | 565 +- .../src/effects/gradients/SkRadialGradient.h | 39 +- .../gradients/SkRadialGradient_Table.h | 139 - .../src/effects/gradients/SkSweepGradient.cpp | 279 +- .../src/effects/gradients/SkSweepGradient.h | 32 +- .../gradients/SkTwoPointConicalGradient.cpp | 625 +-- .../gradients/SkTwoPointConicalGradient.h | 72 +- .../SkTwoPointConicalGradient_gpu.cpp | 1334 +++++ .../gradients/SkTwoPointConicalGradient_gpu.h | 24 + .../gradients/SkTwoPointRadialGradient.cpp | 691 --- .../gradients/SkTwoPointRadialGradient.h | 55 - libskia/src/fonts/SkFontMgr_fontconfig.cpp | 305 -- libskia/src/fonts/SkFontMgr_indirect.cpp | 201 + libskia/src/fonts/SkGScalerContext.cpp | 156 +- libskia/src/fonts/SkGScalerContext.h | 49 +- libskia/src/fonts/SkRandomScalerContext.cpp | 253 + libskia/src/fonts/SkRandomScalerContext.h | 55 + libskia/src/fonts/SkRemotableFontMgr.cpp | 23 + libskia/src/fonts/SkTestScalerContext.cpp | 302 ++ libskia/src/fonts/SkTestScalerContext.h | 109 + libskia/src/gpu/FlingState.cpp | 125 - libskia/src/gpu/GrAAConvexPathRenderer.cpp | 717 --- libskia/src/gpu/GrAAConvexPathRenderer.h | 26 - libskia/src/gpu/GrAAHairLinePathRenderer.cpp | 1042 ---- libskia/src/gpu/GrAAHairLinePathRenderer.h | 65 - libskia/src/gpu/GrAARectRenderer.cpp | 932 ---- libskia/src/gpu/GrAARectRenderer.h | 118 - .../src/gpu/GrAddPathRenderers_default.cpp | 34 - libskia/src/gpu/GrAddPathRenderers_none.cpp | 15 - libskia/src/gpu/GrAllocPool.cpp | 116 - libskia/src/gpu/GrAllocPool.h | 60 - libskia/src/gpu/GrAllocator.h | 276 +- libskia/src/gpu/GrAppliedClip.h | 75 + libskia/src/gpu/GrAtlas.cpp | 261 - libskia/src/gpu/GrAtlas.h | 109 - libskia/src/gpu/GrAuditTrail.cpp | 297 ++ libskia/src/gpu/GrAutoLocaleSetter.h | 86 + libskia/src/gpu/GrBatchAtlas.cpp | 252 + libskia/src/gpu/GrBatchAtlas.h | 261 + libskia/src/gpu/GrBatchFlushState.cpp | 30 + libskia/src/gpu/GrBatchFlushState.h | 211 + libskia/src/gpu/GrBatchTest.cpp | 59 + libskia/src/gpu/GrBatchTest.h | 39 + libskia/src/gpu/GrBinHashKey.h | 102 - libskia/src/gpu/GrBitmapTextContext.cpp | 271 - libskia/src/gpu/GrBitmapTextureMaker.cpp | 71 + libskia/src/gpu/GrBitmapTextureMaker.h | 38 + libskia/src/gpu/GrBlend.cpp | 238 +- libskia/src/gpu/GrBlend.h | 45 - libskia/src/gpu/GrBlurUtils.cpp | 302 ++ libskia/src/gpu/GrBlurUtils.h | 58 + libskia/src/gpu/GrBuffer.cpp | 72 + libskia/src/gpu/GrBufferAllocPool.cpp | 435 +- libskia/src/gpu/GrBufferAllocPool.h | 208 +- libskia/src/gpu/GrCacheID.cpp | 34 - libskia/src/gpu/GrCaps.cpp | 229 + libskia/src/gpu/GrClipData.cpp | 34 - libskia/src/gpu/GrClipMaskCache.cpp | 21 - libskia/src/gpu/GrClipMaskCache.h | 235 - libskia/src/gpu/GrClipMaskManager.cpp | 1044 ---- libskia/src/gpu/GrClipMaskManager.h | 172 - libskia/src/gpu/GrClipStackClip.cpp | 499 ++ libskia/src/gpu/GrClipStackClip.h | 71 + libskia/src/gpu/GrColorSpaceXform.cpp | 128 + libskia/src/gpu/GrContext.cpp | 2260 +++----- libskia/src/gpu/GrContextPriv.h | 65 + libskia/src/gpu/GrCoordTransform.cpp | 60 + libskia/src/gpu/GrDefaultGeoProcFactory.cpp | 317 ++ libskia/src/gpu/GrDefaultGeoProcFactory.h | 136 + libskia/src/gpu/GrDefaultPathRenderer.cpp | 539 -- libskia/src/gpu/GrDefaultPathRenderer.h | 62 - .../src/gpu/GrDistanceFieldTextContext.cpp | 407 -- libskia/src/gpu/GrDrawState.cpp | 475 -- libskia/src/gpu/GrDrawState.h | 1062 ---- libskia/src/gpu/GrDrawTarget.cpp | 1058 ---- libskia/src/gpu/GrDrawTarget.h | 895 ---- libskia/src/gpu/GrDrawTargetCaps.h | 85 - libskia/src/gpu/GrDrawingManager.cpp | 289 + libskia/src/gpu/GrDrawingManager.h | 121 + libskia/src/gpu/GrEffect.cpp | 114 - libskia/src/gpu/GrFixedClip.cpp | 73 + libskia/src/gpu/GrFixedClip.h | 55 + libskia/src/gpu/GrFragmentProcessor.cpp | 403 ++ libskia/src/gpu/GrGeometryBuffer.h | 103 - libskia/src/gpu/GrGeometryProcessor.h | 96 + libskia/src/gpu/GrGlyph.h | 104 + libskia/src/gpu/GrGpu.cpp | 840 ++- libskia/src/gpu/GrGpu.h | 816 +-- libskia/src/gpu/GrGpuCommandBuffer.cpp | 49 + libskia/src/gpu/GrGpuCommandBuffer.h | 113 + libskia/src/gpu/GrGpuFactory.cpp | 48 +- libskia/src/gpu/GrGpuFactory.h | 24 + libskia/src/gpu/GrGpuResource.cpp | 204 + libskia/src/gpu/GrGpuResourceCacheAccess.h | 98 + libskia/src/gpu/GrGpuResourcePriv.h | 90 + libskia/src/gpu/GrGpuResourceRef.cpp | 117 + libskia/src/gpu/GrImageTextureMaker.cpp | 62 + libskia/src/gpu/GrImageTextureMaker.h | 45 + libskia/src/gpu/GrInOrderDrawBuffer.cpp | 862 --- libskia/src/gpu/GrInOrderDrawBuffer.h | 249 - libskia/src/gpu/GrIndexBuffer.h | 33 - libskia/src/gpu/GrInvariantOutput.cpp | 31 + libskia/src/gpu/GrMemory.cpp | 26 - libskia/src/gpu/GrMemoryPool.cpp | 80 +- libskia/src/gpu/GrMemoryPool.h | 124 +- libskia/src/gpu/GrMesh.h | 179 + libskia/src/gpu/GrNonAtomicRef.h | 58 + libskia/src/gpu/GrOpList.cpp | 72 + libskia/src/gpu/GrOpList.h | 142 + libskia/src/gpu/GrOvalRenderer.cpp | 3052 ++++++++--- libskia/src/gpu/GrOvalRenderer.h | 63 +- libskia/src/gpu/GrPLSGeometryProcessor.h | 35 + libskia/src/gpu/GrPaint.cpp | 146 +- libskia/src/gpu/GrPath.cpp | 58 +- libskia/src/gpu/GrPath.h | 50 +- libskia/src/gpu/GrPathProcessor.cpp | 141 + libskia/src/gpu/GrPathProcessor.h | 57 + libskia/src/gpu/GrPathRange.cpp | 55 + libskia/src/gpu/GrPathRange.h | 153 + libskia/src/gpu/GrPathRenderer.cpp | 1 - libskia/src/gpu/GrPathRenderer.h | 305 +- libskia/src/gpu/GrPathRendererChain.cpp | 90 +- .../gpu/GrPathRendererChain.h | 43 +- libskia/src/gpu/GrPathRendering.cpp | 106 + libskia/src/gpu/GrPathRendering.h | 215 + .../GrPathRenderingRenderTargetContext.cpp | 81 + .../gpu/GrPathRenderingRenderTargetContext.h | 44 + libskia/src/gpu/GrPathUtils.cpp | 352 +- libskia/src/gpu/GrPathUtils.h | 75 +- libskia/src/gpu/GrPendingProgramElement.h | 56 + libskia/src/gpu/GrPipeline.cpp | 250 + libskia/src/gpu/GrPipeline.h | 242 + libskia/src/gpu/GrPipelineBuilder.cpp | 83 + libskia/src/gpu/GrPipelineBuilder.h | 320 ++ libskia/src/gpu/GrPlotMgr.h | 74 - libskia/src/gpu/GrPrimitiveProcessor.cpp | 64 + libskia/src/gpu/GrPrimitiveProcessor.h | 233 + libskia/src/gpu/GrProcOptInfo.cpp | 60 + libskia/src/gpu/GrProcOptInfo.h | 85 + libskia/src/gpu/GrProcessor.cpp | 236 + libskia/src/gpu/GrProcessorUnitTest.cpp | 23 + libskia/src/gpu/GrProgramDesc.cpp | 229 + libskia/src/gpu/GrProgramDesc.h | 168 + libskia/src/gpu/GrProgramElement.cpp | 37 + libskia/src/gpu/GrQuad.h | 65 + libskia/{include => src}/gpu/GrRect.h | 27 + libskia/src/gpu/GrRectanizer.cpp | 128 - libskia/src/gpu/GrRectanizer.h | 19 +- libskia/src/gpu/GrRectanizer_fifo.cpp | 121 - libskia/src/gpu/GrRectanizer_pow2.cpp | 59 + libskia/src/gpu/GrRectanizer_pow2.h | 80 + libskia/src/gpu/GrRectanizer_skyline.cpp | 76 +- libskia/src/gpu/GrRectanizer_skyline.h | 62 + libskia/src/gpu/GrRedBlackTree.h | 1115 ---- libskia/src/gpu/GrReducedClip.cpp | 826 ++- libskia/src/gpu/GrReducedClip.h | 107 +- libskia/src/gpu/GrRenderTarget.cpp | 115 +- libskia/src/gpu/GrRenderTargetContext.cpp | 1561 ++++++ libskia/src/gpu/GrRenderTargetContextPriv.h | 121 + libskia/src/gpu/GrRenderTargetOpList.cpp | 584 ++ libskia/src/gpu/GrRenderTargetOpList.h | 177 + libskia/src/gpu/GrRenderTargetPriv.h | 64 + libskia/src/gpu/GrRenderTargetProxy.cpp | 65 + libskia/src/gpu/GrResource.cpp | 61 - libskia/src/gpu/GrResourceCache.cpp | 980 ++-- libskia/src/gpu/GrResourceCache.h | 643 ++- libskia/src/gpu/GrResourceHandle.h | 36 + libskia/src/gpu/GrResourceProvider.cpp | 216 + libskia/src/gpu/GrResourceProvider.h | 184 + libskia/src/gpu/GrSWMaskHelper.cpp | 221 +- libskia/src/gpu/GrSWMaskHelper.h | 98 +- libskia/src/gpu/GrScissorState.h | 40 + libskia/src/gpu/GrShaderCaps.cpp | 227 + libskia/src/gpu/GrShaderVar.cpp | 116 + libskia/src/gpu/GrShape.cpp | 540 ++ libskia/src/gpu/GrShape.h | 463 ++ libskia/src/gpu/GrSoftwarePathRenderer.cpp | 254 +- libskia/src/gpu/GrSoftwarePathRenderer.h | 44 +- libskia/src/gpu/GrStencil.cpp | 395 -- libskia/src/gpu/GrStencil.h | 395 -- .../src/gpu/GrStencilAndCoverPathRenderer.cpp | 103 - .../src/gpu/GrStencilAndCoverPathRenderer.h | 55 - libskia/src/gpu/GrStencilAttachment.cpp | 18 + libskia/src/gpu/GrStencilAttachment.h | 55 + libskia/src/gpu/GrStencilBuffer.cpp | 47 - libskia/src/gpu/GrStencilBuffer.h | 81 - libskia/src/gpu/GrStencilSettings.cpp | 490 ++ libskia/src/gpu/GrStencilSettings.h | 121 + libskia/src/gpu/GrStyle.cpp | 199 + libskia/src/gpu/GrStyle.h | 213 + libskia/src/gpu/GrSurface.cpp | 241 +- libskia/src/gpu/GrSurfaceContext.cpp | 26 + libskia/src/gpu/GrSurfacePriv.h | 66 + libskia/src/gpu/GrSurfaceProxy.cpp | 154 + libskia/src/gpu/GrTBSearch.h | 45 - libskia/src/gpu/GrTHashTable.h | 210 - libskia/src/gpu/GrTRecorder.h | 390 ++ libskia/src/gpu/GrTemplates.h | 68 - libskia/src/gpu/GrTessellator.cpp | 1823 +++++++ libskia/src/gpu/GrTessellator.h | 53 + libskia/src/gpu/GrTest.cpp | 42 - libskia/src/gpu/GrTest.h | 35 - libskia/src/gpu/GrTestUtils.cpp | 341 ++ libskia/src/gpu/GrTextContext.cpp | 27 - libskia/src/gpu/GrTextStrike.cpp | 419 -- libskia/src/gpu/GrTextStrike.h | 137 - libskia/src/gpu/GrTextStrike_impl.h | 111 - libskia/src/gpu/GrTexture.cpp | 223 +- libskia/src/gpu/GrTextureAccess.cpp | 107 - libskia/src/gpu/GrTextureAdjuster.cpp | 167 + libskia/src/gpu/GrTextureAdjuster.h | 66 + libskia/src/gpu/GrTextureContext.cpp | 83 + libskia/src/gpu/GrTextureMaker.cpp | 107 + libskia/src/gpu/GrTextureMaker.h | 74 + libskia/src/gpu/GrTextureOpList.cpp | 113 + libskia/src/gpu/GrTextureOpList.h | 71 + libskia/src/gpu/GrTexturePriv.h | 92 + libskia/src/gpu/GrTextureProducer.cpp | 252 + libskia/src/gpu/GrTextureProducer.h | 146 + libskia/src/gpu/GrTextureProvider.cpp | 208 + libskia/src/gpu/GrTextureProxy.cpp | 39 + .../src/gpu/GrTextureRenderTargetProxy.cpp | 41 + libskia/src/gpu/GrTextureToYUVPlanes.cpp | 238 + libskia/src/gpu/GrTextureToYUVPlanes.h | 19 + libskia/src/gpu/GrTraceMarker.cpp | 102 + libskia/src/gpu/GrTraceMarker.h | 98 + libskia/src/gpu/GrTracing.h | 120 + libskia/src/gpu/GrUserStencilSettings.h | 255 + libskia/src/gpu/GrVertexBuffer.h | 24 - libskia/src/gpu/GrWindowRectangles.h | 101 + libskia/src/gpu/GrWindowRectsState.h | 60 + libskia/src/gpu/GrXferProcessor.cpp | 223 + libskia/src/gpu/GrYUVProvider.cpp | 153 + libskia/src/gpu/GrYUVProvider.h | 67 + libskia/src/gpu/SkGpuDevice.cpp | 2755 +++++----- libskia/src/gpu/SkGpuDevice.h | 253 + libskia/src/gpu/SkGpuDevice_drawTexture.cpp | 252 + libskia/src/gpu/SkGr.cpp | 900 +++- libskia/src/gpu/SkGrFontScaler.cpp | 203 - libskia/src/gpu/SkGrPixelRef.cpp | 191 - libskia/src/gpu/SkGrPriv.h | 163 + .../gpu/batches/GrAAConvexPathRenderer.cpp | 1026 ++++ .../src/gpu/batches/GrAAConvexPathRenderer.h | 23 + .../src/gpu/batches/GrAAConvexTessellator.cpp | 1103 ++++ .../src/gpu/batches/GrAAConvexTessellator.h | 291 + .../batches/GrAADistanceFieldPathRenderer.cpp | 629 +++ .../batches/GrAADistanceFieldPathRenderer.h | 103 + libskia/src/gpu/batches/GrAAFillRectBatch.cpp | 409 ++ libskia/src/gpu/batches/GrAAFillRectBatch.h | 41 + .../gpu/batches/GrAAHairLinePathRenderer.cpp | 1004 ++++ .../gpu/batches/GrAAHairLinePathRenderer.h | 30 + .../GrAALinearizingConvexPathRenderer.cpp | 405 ++ .../GrAALinearizingConvexPathRenderer.h | 23 + .../src/gpu/batches/GrAAStrokeRectBatch.cpp | 642 +++ libskia/src/gpu/batches/GrAAStrokeRectBatch.h | 33 + .../src/gpu/batches/GrAnalyticRectBatch.cpp | 409 ++ libskia/src/gpu/batches/GrAnalyticRectBatch.h | 36 + libskia/src/gpu/batches/GrAtlasTextBatch.cpp | 314 ++ libskia/src/gpu/batches/GrAtlasTextBatch.h | 219 + libskia/src/gpu/batches/GrClearBatch.h | 111 + .../src/gpu/batches/GrClearStencilClipBatch.h | 67 + .../src/gpu/batches/GrCopySurfaceBatch.cpp | 79 + libskia/src/gpu/batches/GrCopySurfaceBatch.h | 89 + .../gpu/batches/GrDashLinePathRenderer.cpp | 56 + .../src/gpu/batches/GrDashLinePathRenderer.h | 30 + .../src/gpu/batches/GrDefaultPathRenderer.cpp | 648 +++ .../src/gpu/batches/GrDefaultPathRenderer.h | 47 + libskia/src/gpu/batches/GrDiscardBatch.h | 57 + libskia/src/gpu/batches/GrDrawAtlasBatch.cpp | 262 + libskia/src/gpu/batches/GrDrawAtlasBatch.h | 77 + libskia/src/gpu/batches/GrDrawOp.cpp | 35 + libskia/src/gpu/batches/GrDrawOp.h | 143 + libskia/src/gpu/batches/GrDrawPathBatch.cpp | 223 + libskia/src/gpu/batches/GrDrawPathBatch.h | 202 + .../src/gpu/batches/GrDrawVerticesBatch.cpp | 326 ++ libskia/src/gpu/batches/GrDrawVerticesBatch.h | 80 + .../src/gpu/batches/GrMSAAPathRenderer.cpp | 728 +++ libskia/src/gpu/batches/GrMSAAPathRenderer.h | 35 + libskia/src/gpu/batches/GrMeshDrawOp.cpp | 109 + libskia/src/gpu/batches/GrMeshDrawOp.h | 92 + libskia/src/gpu/batches/GrNinePatch.cpp | 188 + libskia/src/gpu/batches/GrNinePatch.h | 26 + .../src/gpu/batches/GrNonAAFillRectBatch.cpp | 225 + .../src/gpu/batches/GrNonAAFillRectBatch.h | 33 + .../GrNonAAFillRectPerspectiveBatch.cpp | 271 + .../gpu/batches/GrNonAAStrokeRectBatch.cpp | 216 + .../src/gpu/batches/GrNonAAStrokeRectBatch.h | 30 + libskia/src/gpu/batches/GrOp.cpp | 63 + libskia/src/gpu/batches/GrOp.h | 232 + libskia/src/gpu/batches/GrPLSPathRenderer.cpp | 963 ++++ libskia/src/gpu/batches/GrPLSPathRenderer.h | 48 + .../src/gpu/batches/GrPathStencilSettings.h | 160 + .../src/gpu/batches/GrRectBatchFactory.cpp | 35 + libskia/src/gpu/batches/GrRectBatchFactory.h | 83 + libskia/src/gpu/batches/GrRegionBatch.cpp | 167 + libskia/src/gpu/batches/GrRegionBatch.h | 23 + .../src/gpu/batches/GrShadowRRectBatch.cpp | 966 ++++ libskia/src/gpu/batches/GrShadowRRectBatch.h | 26 + .../batches/GrStencilAndCoverPathRenderer.cpp | 177 + .../batches/GrStencilAndCoverPathRenderer.h | 44 + libskia/src/gpu/batches/GrStencilPathBatch.h | 87 + .../batches/GrTessellatingPathRenderer.cpp | 398 ++ .../gpu/batches/GrTessellatingPathRenderer.h | 33 + libskia/src/gpu/batches/GrTestBatch.h | 66 + libskia/src/gpu/effects/Gr1DKernelEffect.h | 11 +- libskia/src/gpu/effects/GrBezierEffect.cpp | 831 ++- libskia/src/gpu/effects/GrBezierEffect.h | 287 +- libskia/src/gpu/effects/GrBicubicEffect.cpp | 249 +- libskia/src/gpu/effects/GrBicubicEffect.h | 87 +- .../src/gpu/effects/GrBitmapTextGeoProc.cpp | 193 + libskia/src/gpu/effects/GrBitmapTextGeoProc.h | 67 + .../gpu/effects/GrConfigConversionEffect.cpp | 320 +- .../gpu/effects/GrConfigConversionEffect.h | 43 +- .../src/gpu/effects/GrConstColorProcessor.cpp | 129 + .../src/gpu/effects/GrConvexPolyEffect.cpp | 379 ++ libskia/src/gpu/effects/GrConvexPolyEffect.h | 93 + .../src/gpu/effects/GrConvolutionEffect.cpp | 218 +- libskia/src/gpu/effects/GrConvolutionEffect.h | 71 +- libskia/src/gpu/effects/GrCoverageSetOpXP.cpp | 344 ++ .../effects/GrCustomCoordsTextureEffect.cpp | 106 - .../gpu/effects/GrCustomCoordsTextureEffect.h | 50 - libskia/src/gpu/effects/GrCustomXfermode.cpp | 400 ++ libskia/src/gpu/effects/GrDashingEffect.cpp | 1298 +++++ libskia/src/gpu/effects/GrDashingEffect.h | 36 + libskia/src/gpu/effects/GrDisableColorXP.cpp | 109 + libskia/src/gpu/effects/GrDisableColorXP.h | 48 + .../gpu/effects/GrDistanceFieldGeoProc.cpp | 840 +++ .../src/gpu/effects/GrDistanceFieldGeoProc.h | 237 + .../effects/GrDistanceFieldTextureEffect.cpp | 117 - .../effects/GrDistanceFieldTextureEffect.h | 51 - libskia/src/gpu/effects/GrDitherEffect.cpp | 99 + libskia/src/gpu/effects/GrDitherEffect.h | 24 + libskia/src/gpu/effects/GrGammaEffect.cpp | 148 + libskia/src/gpu/effects/GrGammaEffect.h | 47 + .../gpu/effects/GrMatrixConvolutionEffect.cpp | 269 + .../gpu/effects/GrMatrixConvolutionEffect.h | 93 + libskia/src/gpu/effects/GrOvalEffect.cpp | 413 ++ libskia/src/gpu/effects/GrOvalEffect.h | 25 + .../gpu/effects/GrPorterDuffXferProcessor.cpp | 923 ++++ libskia/src/gpu/effects/GrRRectEffect.cpp | 780 +++ libskia/src/gpu/effects/GrRRectEffect.h | 27 + libskia/src/gpu/effects/GrShadowGeoProc.cpp | 104 + libskia/src/gpu/effects/GrShadowGeoProc.h | 56 + .../src/gpu/effects/GrSimpleTextureEffect.cpp | 98 +- .../src/gpu/effects/GrSimpleTextureEffect.h | 80 +- .../src/gpu/effects/GrSingleTextureEffect.cpp | 33 +- .../src/gpu/effects/GrSingleTextureEffect.h | 57 +- libskia/src/gpu/effects/GrTextureDomain.cpp | 456 +- libskia/src/gpu/effects/GrTextureDomain.h | 180 +- .../src/gpu/effects/GrTextureStripAtlas.cpp | 160 +- libskia/src/gpu/effects/GrVertexEffect.h | 37 - .../effects/GrXfermodeFragmentProcessor.cpp | 312 ++ libskia/src/gpu/effects/GrYUVEffect.cpp | 407 ++ libskia/src/gpu/effects/GrYUVEffect.h | 50 + libskia/src/gpu/gl/GrGLAssembleInterface.cpp | 959 ++++ libskia/src/gpu/gl/GrGLBuffer.cpp | 288 + libskia/src/gpu/gl/GrGLBuffer.h | 67 + libskia/src/gpu/gl/GrGLBufferImpl.cpp | 165 - libskia/src/gpu/gl/GrGLBufferImpl.h | 60 - libskia/src/gpu/gl/GrGLCaps.cpp | 2195 ++++++-- libskia/src/gpu/gl/GrGLCaps.h | 492 +- libskia/src/gpu/gl/GrGLContext.cpp | 132 +- libskia/src/gpu/gl/GrGLContext.h | 140 +- .../gpu/gl/GrGLCreateNativeInterface_none.cpp | 2 +- .../src/gpu/gl/GrGLCreateNullInterface.cpp | 1144 ++-- .../src/gpu/gl/GrGLDefaultInterface_none.cpp | 2 +- libskia/src/gpu/gl/GrGLDefines.h | 562 +- libskia/src/gpu/gl/GrGLEffect.h | 113 - libskia/src/gpu/gl/GrGLExtensions.cpp | 141 +- libskia/src/gpu/gl/GrGLGLSL.cpp | 54 + libskia/src/gpu/gl/GrGLGLSL.h | 25 + libskia/src/gpu/gl/GrGLGpu.cpp | 4698 +++++++++++++++++ libskia/src/gpu/gl/GrGLGpu.h | 661 +++ libskia/src/gpu/gl/GrGLGpuCommandBuffer.h | 88 + libskia/src/gpu/gl/GrGLGpuProgramCache.cpp | 222 + libskia/src/gpu/gl/GrGLIRect.h | 21 +- libskia/src/gpu/gl/GrGLIndexBuffer.cpp | 57 - libskia/src/gpu/gl/GrGLIndexBuffer.h | 57 - libskia/src/gpu/gl/GrGLInterface.cpp | 1044 ++-- libskia/src/gpu/gl/GrGLNoOpInterface.cpp | 658 --- libskia/src/gpu/gl/GrGLNoOpInterface.h | 378 -- libskia/src/gpu/gl/GrGLPath.cpp | 314 +- libskia/src/gpu/gl/GrGLPath.h | 34 +- libskia/src/gpu/gl/GrGLPathRange.cpp | 110 + libskia/src/gpu/gl/GrGLPathRange.h | 66 + libskia/src/gpu/gl/GrGLPathRendering.cpp | 339 ++ libskia/src/gpu/gl/GrGLPathRendering.h | 132 + libskia/src/gpu/gl/GrGLProgram.cpp | 426 +- libskia/src/gpu/gl/GrGLProgram.h | 208 +- libskia/src/gpu/gl/GrGLProgramDataManager.cpp | 278 + libskia/src/gpu/gl/GrGLProgramDataManager.h | 115 + libskia/src/gpu/gl/GrGLProgramDesc.cpp | 289 - libskia/src/gpu/gl/GrGLProgramDesc.h | 227 - libskia/src/gpu/gl/GrGLProgramEffects.cpp | 586 -- libskia/src/gpu/gl/GrGLProgramEffects.h | 325 -- libskia/src/gpu/gl/GrGLRenderTarget.cpp | 252 +- libskia/src/gpu/gl/GrGLRenderTarget.h | 103 +- libskia/src/gpu/gl/GrGLSL.cpp | 92 - libskia/src/gpu/gl/GrGLShaderBuilder.cpp | 986 ---- libskia/src/gpu/gl/GrGLShaderBuilder.h | 475 -- libskia/src/gpu/gl/GrGLShaderVar.h | 360 -- libskia/src/gpu/gl/GrGLStencilAttachment.cpp | 44 + libskia/src/gpu/gl/GrGLStencilAttachment.h | 67 + libskia/src/gpu/gl/GrGLStencilBuffer.cpp | 39 - libskia/src/gpu/gl/GrGLStencilBuffer.h | 62 - libskia/src/gpu/gl/GrGLTestInterface.cpp | 325 ++ libskia/src/gpu/gl/GrGLTestInterface.h | 341 ++ libskia/src/gpu/gl/GrGLTexture.cpp | 132 +- libskia/src/gpu/gl/GrGLTexture.h | 93 +- .../src/gpu/gl/GrGLTextureRenderTarget.cpp | 53 + libskia/src/gpu/gl/GrGLTextureRenderTarget.h | 84 + libskia/src/gpu/gl/GrGLUniformHandle.h | 15 - libskia/src/gpu/gl/GrGLUniformHandler.cpp | 175 + libskia/src/gpu/gl/GrGLUniformHandler.h | 85 + libskia/src/gpu/gl/GrGLUniformManager.cpp | 279 - libskia/src/gpu/gl/GrGLUniformManager.h | 118 - libskia/src/gpu/gl/GrGLUtil.cpp | 295 +- libskia/src/gpu/gl/GrGLUtil.h | 89 +- libskia/src/gpu/gl/GrGLVaryingHandler.cpp | 37 + libskia/src/gpu/gl/GrGLVaryingHandler.h | 36 + libskia/src/gpu/gl/GrGLVertexArray.cpp | 198 +- libskia/src/gpu/gl/GrGLVertexArray.h | 136 +- libskia/src/gpu/gl/GrGLVertexBuffer.cpp | 58 - libskia/src/gpu/gl/GrGLVertexBuffer.h | 57 - libskia/src/gpu/gl/GrGLVertexEffect.h | 52 - libskia/src/gpu/gl/GrGpuGL.cpp | 2705 ---------- libskia/src/gpu/gl/GrGpuGL.h | 459 -- libskia/src/gpu/gl/GrGpuGL_program.cpp | 381 -- libskia/src/gpu/gl/SkGLContextHelper.cpp | 138 - .../GrGLCreateNativeInterface_android.cpp | 649 +-- .../gl/android/SkNativeGLContext_android.cpp | 173 - .../gpu/gl/angle/GrGLCreateANGLEInterface.cpp | 159 - libskia/src/gpu/gl/angle/SkANGLEGLContext.cpp | 113 - .../gpu/gl/builders/GrGLProgramBuilder.cpp | 241 + .../src/gpu/gl/builders/GrGLProgramBuilder.h | 71 + .../src/gpu/gl/builders/GrGLSLPrettyPrint.cpp | 204 + .../gl/builders/GrGLShaderStringBuilder.cpp | 164 + .../gpu/gl/builders/GrGLShaderStringBuilder.h | 25 + libskia/src/gpu/gl/debug/GrBufferObj.cpp | 31 - libskia/src/gpu/gl/debug/GrBufferObj.h | 68 - libskia/src/gpu/gl/debug/GrDebugGL.cpp | 211 - libskia/src/gpu/gl/debug/GrDebugGL.h | 160 - libskia/src/gpu/gl/debug/GrFBBindableObj.h | 88 - libskia/src/gpu/gl/debug/GrFakeRefObj.h | 94 - libskia/src/gpu/gl/debug/GrFrameBufferObj.cpp | 67 - libskia/src/gpu/gl/debug/GrFrameBufferObj.h | 68 - .../gpu/gl/debug/GrGLCreateDebugInterface.cpp | 933 ---- libskia/src/gpu/gl/debug/GrProgramObj.cpp | 27 - libskia/src/gpu/gl/debug/GrProgramObj.h | 43 - libskia/src/gpu/gl/debug/GrRenderBufferObj.h | 40 - libskia/src/gpu/gl/debug/GrShaderObj.cpp | 14 - libskia/src/gpu/gl/debug/GrShaderObj.h | 36 - libskia/src/gpu/gl/debug/GrTextureObj.cpp | 14 - libskia/src/gpu/gl/debug/GrTextureObj.h | 57 - libskia/src/gpu/gl/debug/GrTextureUnitObj.cpp | 31 - libskia/src/gpu/gl/debug/GrTextureUnitObj.h | 44 - libskia/src/gpu/gl/debug/GrVertexArrayObj.h | 21 - libskia/src/gpu/gl/debug/SkDebugGLContext.cpp | 13 - .../gl/egl/GrGLCreateNativeInterface_egl.cpp | 29 + .../glfw/GrGLCreateNativeInterface_glfw.cpp | 27 + .../gl/glx/GrGLCreateNativeInterface_glx.cpp | 33 + .../gl/iOS/GrGLCreateNativeInterface_iOS.cpp | 177 +- .../src/gpu/gl/iOS/SkNativeGLContext_iOS.mm | 64 - .../gl/mac/GrGLCreateNativeInterface_mac.cpp | 246 +- .../src/gpu/gl/mac/SkNativeGLContext_mac.cpp | 81 - .../gpu/gl/mesa/GrGLCreateMesaInterface.cpp | 228 - libskia/src/gpu/gl/mesa/SkMesaGLContext.cpp | 108 - libskia/src/gpu/gl/mesa/osmesa_wrapper.h | 1 - .../gpu/gl/nacl/SkNativeGLContext_nacl.cpp | 37 - .../unix/GrGLCreateNativeInterface_unix.cpp | 284 - .../gpu/gl/unix/SkNativeGLContext_unix.cpp | 291 - .../gl/win/GrGLCreateNativeInterface_win.cpp | 336 +- .../src/gpu/gl/win/SkNativeGLContext_win.cpp | 120 - libskia/src/gpu/glsl/GrGLSL.cpp | 59 + libskia/src/gpu/glsl/GrGLSLBlend.cpp | 483 ++ libskia/src/gpu/glsl/GrGLSLBlend.h | 28 + .../gpu/glsl/GrGLSLColorSpaceXformHelper.h | 40 + .../src/gpu/glsl/GrGLSLFragmentProcessor.cpp | 82 + .../src/gpu/glsl/GrGLSLFragmentProcessor.h | 208 + .../gpu/glsl/GrGLSLFragmentShaderBuilder.cpp | 382 ++ .../gpu/glsl/GrGLSLFragmentShaderBuilder.h | 254 + .../src/gpu/glsl/GrGLSLGeometryProcessor.cpp | 119 + .../src/gpu/glsl/GrGLSLGeometryProcessor.h | 89 + .../gpu/glsl/GrGLSLGeometryShaderBuilder.cpp | 56 + .../gpu/glsl/GrGLSLGeometryShaderBuilder.h | 45 + libskia/src/gpu/glsl/GrGLSLPLSPathRendering.h | 12 + .../src/gpu/glsl/GrGLSLPrimitiveProcessor.cpp | 57 + .../src/gpu/glsl/GrGLSLPrimitiveProcessor.h | 142 + libskia/src/gpu/glsl/GrGLSLProgramBuilder.cpp | 496 ++ libskia/src/gpu/glsl/GrGLSLProgramBuilder.h | 192 + .../src/gpu/glsl/GrGLSLProgramDataManager.cpp | 33 + .../src/gpu/glsl/GrGLSLProgramDataManager.h | 67 + libskia/src/gpu/glsl/GrGLSLShaderBuilder.cpp | 238 + libskia/src/gpu/glsl/GrGLSLShaderBuilder.h | 264 + libskia/src/gpu/glsl/GrGLSLUniformHandler.h | 89 + libskia/src/gpu/glsl/GrGLSLUtil.cpp | 52 + libskia/src/gpu/glsl/GrGLSLUtil.h | 19 + libskia/src/gpu/glsl/GrGLSLVarying.cpp | 155 + libskia/src/gpu/glsl/GrGLSLVarying.h | 186 + .../gpu/glsl/GrGLSLVertexShaderBuilder.cpp | 57 + .../src/gpu/glsl/GrGLSLVertexShaderBuilder.h | 34 + libskia/src/gpu/glsl/GrGLSLXferProcessor.cpp | 123 + libskia/src/gpu/glsl/GrGLSLXferProcessor.h | 120 + .../gpu/instanced/GLInstancedRendering.cpp | 324 ++ .../src/gpu/instanced/GLInstancedRendering.h | 66 + .../src/gpu/instanced/InstanceProcessor.cpp | 2095 ++++++++ libskia/src/gpu/instanced/InstanceProcessor.h | 69 + .../src/gpu/instanced/InstancedRendering.cpp | 496 ++ .../src/gpu/instanced/InstancedRendering.h | 205 + .../gpu/instanced/InstancedRenderingTypes.h | 192 + libskia/src/gpu/text/GrAtlasTextBlob.cpp | 567 ++ libskia/src/gpu/text/GrAtlasTextBlob.h | 567 ++ .../gpu/text/GrAtlasTextBlob_regenInBatch.cpp | 314 ++ libskia/src/gpu/text/GrAtlasTextContext.cpp | 436 ++ libskia/src/gpu/text/GrAtlasTextContext.h | 98 + libskia/src/gpu/text/GrBatchFontCache.cpp | 379 ++ libskia/src/gpu/text/GrBatchFontCache.h | 241 + .../gpu/text/GrDistanceFieldAdjustTable.cpp | 98 + .../src/gpu/text/GrDistanceFieldAdjustTable.h | 35 + .../gpu/text/GrStencilAndCoverTextContext.cpp | 740 +++ .../gpu/text/GrStencilAndCoverTextContext.h | 160 + libskia/src/gpu/text/GrTextBlobCache.cpp | 26 + libskia/src/gpu/text/GrTextBlobCache.h | 144 + libskia/src/gpu/text/GrTextUtils.cpp | 570 ++ libskia/src/gpu/text/GrTextUtils.h | 106 + libskia/src/gpu/vk/GrVkBackendContext.cpp | 274 + libskia/src/gpu/vk/GrVkBuffer.cpp | 224 + libskia/src/gpu/vk/GrVkBuffer.h | 121 + libskia/src/gpu/vk/GrVkCaps.cpp | 270 + libskia/src/gpu/vk/GrVkCaps.h | 142 + libskia/src/gpu/vk/GrVkCommandBuffer.cpp | 696 +++ libskia/src/gpu/vk/GrVkCommandBuffer.h | 352 ++ libskia/src/gpu/vk/GrVkCopyManager.cpp | 406 ++ libskia/src/gpu/vk/GrVkCopyManager.h | 55 + libskia/src/gpu/vk/GrVkCopyPipeline.cpp | 190 + libskia/src/gpu/vk/GrVkCopyPipeline.h | 43 + libskia/src/gpu/vk/GrVkDescriptorPool.cpp | 51 + libskia/src/gpu/vk/GrVkDescriptorPool.h | 51 + libskia/src/gpu/vk/GrVkDescriptorSet.cpp | 34 + libskia/src/gpu/vk/GrVkDescriptorSet.h | 44 + .../src/gpu/vk/GrVkDescriptorSetManager.cpp | 311 ++ libskia/src/gpu/vk/GrVkDescriptorSetManager.h | 95 + libskia/src/gpu/vk/GrVkExtensions.cpp | 259 + libskia/src/gpu/vk/GrVkExtensions.h | 46 + libskia/src/gpu/vk/GrVkFramebuffer.cpp | 57 + libskia/src/gpu/vk/GrVkFramebuffer.h | 50 + libskia/src/gpu/vk/GrVkGpu.cpp | 1887 +++++++ libskia/src/gpu/vk/GrVkGpu.h | 286 + libskia/src/gpu/vk/GrVkGpuCommandBuffer.cpp | 576 ++ libskia/src/gpu/vk/GrVkGpuCommandBuffer.h | 99 + libskia/src/gpu/vk/GrVkImage.cpp | 161 + libskia/src/gpu/vk/GrVkImage.h | 141 + libskia/src/gpu/vk/GrVkImageView.cpp | 45 + libskia/src/gpu/vk/GrVkImageView.h | 48 + libskia/src/gpu/vk/GrVkIndexBuffer.cpp | 74 + libskia/src/gpu/vk/GrVkIndexBuffer.h | 38 + libskia/src/gpu/vk/GrVkInterface.cpp | 330 ++ libskia/src/gpu/vk/GrVkMemory.cpp | 642 +++ libskia/src/gpu/vk/GrVkMemory.h | 167 + libskia/src/gpu/vk/GrVkPipeline.cpp | 547 ++ libskia/src/gpu/vk/GrVkPipeline.h | 59 + libskia/src/gpu/vk/GrVkPipelineState.cpp | 524 ++ libskia/src/gpu/vk/GrVkPipelineState.h | 238 + .../src/gpu/vk/GrVkPipelineStateBuilder.cpp | 169 + libskia/src/gpu/vk/GrVkPipelineStateBuilder.h | 75 + libskia/src/gpu/vk/GrVkPipelineStateCache.cpp | 158 + .../gpu/vk/GrVkPipelineStateDataManager.cpp | 286 + .../src/gpu/vk/GrVkPipelineStateDataManager.h | 83 + libskia/src/gpu/vk/GrVkRenderPass.cpp | 266 + libskia/src/gpu/vk/GrVkRenderPass.h | 146 + libskia/src/gpu/vk/GrVkRenderTarget.cpp | 379 ++ libskia/src/gpu/vk/GrVkRenderTarget.h | 147 + libskia/src/gpu/vk/GrVkResource.h | 213 + libskia/src/gpu/vk/GrVkResourceProvider.cpp | 482 ++ libskia/src/gpu/vk/GrVkResourceProvider.h | 261 + libskia/src/gpu/vk/GrVkSampler.cpp | 96 + libskia/src/gpu/vk/GrVkSampler.h | 48 + libskia/src/gpu/vk/GrVkStencilAttachment.cpp | 99 + libskia/src/gpu/vk/GrVkStencilAttachment.h | 57 + libskia/src/gpu/vk/GrVkTexture.cpp | 236 + libskia/src/gpu/vk/GrVkTexture.h | 59 + .../src/gpu/vk/GrVkTextureRenderTarget.cpp | 184 + libskia/src/gpu/vk/GrVkTextureRenderTarget.h | 123 + libskia/src/gpu/vk/GrVkTransferBuffer.cpp | 61 + libskia/src/gpu/vk/GrVkTransferBuffer.h | 56 + libskia/src/gpu/vk/GrVkUniformBuffer.cpp | 103 + libskia/src/gpu/vk/GrVkUniformBuffer.h | 58 + libskia/src/gpu/vk/GrVkUniformHandler.cpp | 234 + libskia/src/gpu/vk/GrVkUniformHandler.h | 117 + libskia/src/gpu/vk/GrVkUtil.cpp | 366 ++ libskia/src/gpu/vk/GrVkUtil.h | 53 + libskia/src/gpu/vk/GrVkVaryingHandler.cpp | 88 + libskia/src/gpu/vk/GrVkVaryingHandler.h | 27 + libskia/src/gpu/vk/GrVkVertexBuffer.cpp | 73 + libskia/src/gpu/vk/GrVkVertexBuffer.h | 37 + libskia/src/image/SkImage.cpp | 459 +- libskia/src/image/SkImagePriv.cpp | 143 - libskia/src/image/SkImagePriv.h | 70 - libskia/src/image/SkImageShader.cpp | 398 ++ libskia/src/image/SkImageShader.h | 53 + libskia/src/image/SkImageShaderContext.h | 34 + libskia/src/image/SkImage_Base.h | 81 +- libskia/src/image/SkImage_Codec.cpp | 78 - libskia/src/image/SkImage_Generator.cpp | 102 + libskia/src/image/SkImage_Gpu.cpp | 735 ++- libskia/src/image/SkImage_Gpu.h | 65 + libskia/src/image/SkImage_Picture.cpp | 66 - libskia/src/image/SkImage_Raster.cpp | 363 +- libskia/src/image/SkReadPixelsRec.h | 41 + libskia/src/image/SkSurface.cpp | 176 +- libskia/src/image/SkSurface_Base.h | 88 +- libskia/src/image/SkSurface_Gpu.cpp | 316 +- libskia/src/image/SkSurface_Gpu.h | 44 + libskia/src/image/SkSurface_Picture.cpp | 92 - libskia/src/image/SkSurface_Raster.cpp | 168 +- .../src/images/SkDecodingImageGenerator.cpp | 287 - libskia/src/images/SkDecodingImageGenerator.h | 141 - libskia/src/images/SkForceLinking.cpp | 33 - libskia/src/images/SkImageDecoder.cpp | 307 -- .../images/SkImageDecoder_FactoryDefault.cpp | 36 - .../SkImageDecoder_FactoryRegistrar.cpp | 63 - libskia/src/images/SkImageDecoder_libbmp.cpp | 163 - libskia/src/images/SkImageDecoder_libgif.cpp | 538 -- libskia/src/images/SkImageDecoder_libico.cpp | 417 -- libskia/src/images/SkImageDecoder_libjpeg.cpp | 1249 ----- libskia/src/images/SkImageDecoder_libpng.cpp | 1297 ----- libskia/src/images/SkImageDecoder_libwebp.cpp | 604 --- libskia/src/images/SkImageDecoder_wbmp.cpp | 173 - libskia/src/images/SkImageEncoder.cpp | 62 +- libskia/src/images/SkImageEncoderPriv.h | 49 + libskia/src/images/SkImageEncoder_Factory.cpp | 23 - libskia/src/images/SkImageEncoder_argb.cpp | 119 - libskia/src/images/SkImageRef.cpp | 198 - libskia/src/images/SkImageRefPool.cpp | 192 - libskia/src/images/SkImageRefPool.h | 49 - libskia/src/images/SkImageRef_GlobalPool.cpp | 100 - libskia/src/images/SkImageRef_ashmem.cpp | 229 - libskia/src/images/SkImageRef_ashmem.h | 47 - libskia/src/images/SkImages.cpp | 21 - libskia/src/images/SkJPEGImageEncoder.cpp | 172 + libskia/src/images/SkJPEGWriteUtility.cpp | 64 + .../{SkJpegUtility.h => SkJPEGWriteUtility.h} | 20 - libskia/src/images/SkJpegUtility.cpp | 170 - libskia/src/images/SkKTXImageEncoder.cpp | 35 + libskia/src/images/SkMovie.cpp | 95 - libskia/src/images/SkMovie_gif.cpp | 449 -- libskia/src/images/SkPNGImageEncoder.cpp | 336 ++ libskia/src/images/SkPageFlipper.cpp | 76 - libskia/src/images/SkScaledBitmapSampler.cpp | 852 --- libskia/src/images/SkScaledBitmapSampler.h | 94 - libskia/src/images/SkStreamHelpers.cpp | 40 - libskia/src/images/SkStreamHelpers.h | 27 - libskia/src/images/SkWEBPImageEncoder.cpp | 228 + libskia/src/images/bmpdecoderhelper.cpp | 369 -- libskia/src/images/bmpdecoderhelper.h | 116 - libskia/src/images/transform_scanline.h | 130 +- libskia/src/lazy/SkDiscardableMemoryPool.cpp | 258 + libskia/src/lazy/SkDiscardableMemoryPool.h | 69 + libskia/src/opts/Sk4px_NEON.h | 99 + libskia/src/opts/Sk4px_SSE2.h | 104 + libskia/src/opts/Sk4px_none.h | 109 + libskia/src/opts/SkBitmapFilter_opts.h | 940 ++++ libskia/src/opts/SkBitmapFilter_opts_SSE2.cpp | 633 --- libskia/src/opts/SkBitmapFilter_opts_SSE2.h | 37 - .../src/opts/SkBitmapProcState_arm_neon.cpp | 454 +- .../src/opts/SkBitmapProcState_filter_neon.h | 24 +- .../SkBitmapProcState_matrixProcs_neon.cpp | 140 +- .../SkBitmapProcState_matrix_clamp_neon.h | 911 ---- .../src/opts/SkBitmapProcState_matrix_neon.h | 500 ++ .../SkBitmapProcState_matrix_repeat_neon.h | 542 -- .../src/opts/SkBitmapProcState_opts_SSE2.cpp | 207 +- .../src/opts/SkBitmapProcState_opts_SSE2.h | 12 +- .../src/opts/SkBitmapProcState_opts_SSSE3.cpp | 55 +- .../src/opts/SkBitmapProcState_opts_SSSE3.h | 4 + .../src/opts/SkBitmapProcState_opts_arm.cpp | 234 - .../opts/SkBitmapProcState_opts_mips_dsp.cpp | 259 + .../src/opts/SkBitmapProcState_opts_none.cpp | 6 +- libskia/src/opts/SkBlend_opts.h | 187 + libskia/src/opts/SkBlitMask_opts.h | 206 + libskia/src/opts/SkBlitMask_opts_arm.cpp | 33 +- libskia/src/opts/SkBlitMask_opts_arm_neon.cpp | 203 +- libskia/src/opts/SkBlitMask_opts_arm_neon.h | 9 +- libskia/src/opts/SkBlitMask_opts_none.cpp | 18 +- libskia/src/opts/SkBlitRect_opts_SSE2.cpp | 133 - libskia/src/opts/SkBlitRect_opts_SSE2.h | 23 - libskia/src/opts/SkBlitRow_opts.h | 207 + libskia/src/opts/SkBlitRow_opts_SSE2.cpp | 961 ++-- libskia/src/opts/SkBlitRow_opts_SSE2.h | 27 +- libskia/src/opts/SkBlitRow_opts_arm.cpp | 369 +- libskia/src/opts/SkBlitRow_opts_arm_neon.cpp | 1416 +++-- libskia/src/opts/SkBlitRow_opts_arm_neon.h | 6 +- libskia/src/opts/SkBlitRow_opts_mips_dsp.cpp | 958 ++++ libskia/src/opts/SkBlitRow_opts_none.cpp | 16 +- libskia/src/opts/SkBlurImageFilter_opts.h | 323 ++ libskia/src/opts/SkBlurImage_opts.h | 20 - libskia/src/opts/SkBlurImage_opts_SSE2.cpp | 117 - libskia/src/opts/SkBlurImage_opts_SSE2.h | 13 - libskia/src/opts/SkBlurImage_opts_neon.cpp | 101 - libskia/src/opts/SkBlurImage_opts_neon.h | 13 - libskia/src/opts/SkBlurImage_opts_none.cpp | 15 - libskia/src/opts/SkCachePreload_arm.h | 34 - libskia/src/opts/SkChecksum_opts.h | 216 + libskia/src/opts/SkColorCubeFilter_opts.h | 84 + libskia/src/opts/SkColor_opts_SSE2.h | 305 ++ libskia/src/opts/SkColor_opts_neon.h | 7 + .../src/opts/SkMorphologyImageFilter_opts.h | 137 + libskia/src/opts/SkMorphology_opts.h | 27 - libskia/src/opts/SkMorphology_opts_SSE2.cpp | 79 - libskia/src/opts/SkMorphology_opts_SSE2.h | 15 - libskia/src/opts/SkMorphology_opts_neon.cpp | 80 - libskia/src/opts/SkMorphology_opts_neon.h | 15 - libskia/src/opts/SkMorphology_opts_none.cpp | 12 - libskia/src/opts/SkNx_neon.h | 565 ++ libskia/src/opts/SkNx_sse.h | 758 +++ libskia/src/opts/SkOpts_avx.cpp | 19 + libskia/src/opts/SkOpts_crc32.cpp | 17 + libskia/src/opts/SkOpts_hsw.cpp | 24 + libskia/src/opts/SkOpts_sse41.cpp | 26 + libskia/src/opts/SkOpts_sse42.cpp | 18 + libskia/src/opts/SkOpts_ssse3.cpp | 32 + libskia/src/opts/SkRasterPipeline_opts.h | 987 ++++ libskia/src/opts/SkSwizzler_opts.h | 846 +++ libskia/src/opts/SkTextureCompressor_opts.h | 266 + libskia/src/opts/SkUtils_opts_SSE2.cpp | 71 - libskia/src/opts/SkUtils_opts_SSE2.h | 13 - libskia/src/opts/SkUtils_opts_none.cpp | 18 - libskia/src/opts/SkXfermode_opts.h | 360 ++ libskia/src/opts/SkXfermode_opts_arm.cpp | 26 - libskia/src/opts/SkXfermode_opts_arm_neon.cpp | 937 ---- libskia/src/opts/SkXfermode_opts_arm_neon.h | 35 - libskia/src/opts/SkXfermode_opts_none.cpp | 17 - libskia/src/opts/memset.arm.S | 111 - libskia/src/opts/memset16_neon.S | 143 - libskia/src/opts/memset32_neon.S | 113 - .../src/opts/morphology_opts_check_mac.cpp | 9 - libskia/src/opts/opts_check_SSE2.cpp | 298 -- libskia/src/opts/opts_check_arm.cpp | 110 - libskia/src/opts/opts_check_mac.cpp | 23 - libskia/src/opts/opts_check_x86.cpp | 150 + libskia/src/pathops/SkAddIntersections.cpp | 356 +- libskia/src/pathops/SkAddIntersections.h | 7 +- .../src/pathops/SkDConicLineIntersection.cpp | 384 ++ libskia/src/pathops/SkDCubicIntersection.cpp | 647 --- .../src/pathops/SkDCubicLineIntersection.cpp | 199 +- libskia/src/pathops/SkDCubicToQuads.cpp | 160 +- libskia/src/pathops/SkDLineIntersection.cpp | 159 +- libskia/src/pathops/SkDQuadImplicit.cpp | 117 - libskia/src/pathops/SkDQuadImplicit.h | 39 - libskia/src/pathops/SkDQuadIntersection.cpp | 553 -- .../src/pathops/SkDQuadLineIntersection.cpp | 203 +- libskia/src/pathops/SkIntersectionHelper.h | 102 +- libskia/src/pathops/SkIntersections.cpp | 168 +- libskia/src/pathops/SkIntersections.h | 187 +- libskia/src/pathops/SkLineParameters.h | 86 +- libskia/src/pathops/SkOpAngle.cpp | 1230 +++-- libskia/src/pathops/SkOpAngle.h | 148 +- libskia/src/pathops/SkOpBuilder.cpp | 192 + libskia/src/pathops/SkOpCoincidence.cpp | 1395 +++++ libskia/src/pathops/SkOpCoincidence.h | 303 ++ libskia/src/pathops/SkOpContour.cpp | 418 +- libskia/src/pathops/SkOpContour.h | 483 +- libskia/src/pathops/SkOpCubicHull.cpp | 150 + libskia/src/pathops/SkOpEdgeBuilder.cpp | 189 +- libskia/src/pathops/SkOpEdgeBuilder.h | 40 +- libskia/src/pathops/SkOpSegment.cpp | 3981 +++++--------- libskia/src/pathops/SkOpSegment.h | 660 +-- libskia/src/pathops/SkOpSpan.cpp | 477 ++ libskia/src/pathops/SkOpSpan.h | 562 +- libskia/src/pathops/SkOpTAllocator.h | 33 + libskia/src/pathops/SkPathOpsBounds.cpp | 40 - libskia/src/pathops/SkPathOpsBounds.h | 29 +- libskia/src/pathops/SkPathOpsCommon.cpp | 826 +-- libskia/src/pathops/SkPathOpsCommon.h | 32 +- libskia/src/pathops/SkPathOpsConic.cpp | 170 + libskia/src/pathops/SkPathOpsConic.h | 132 + libskia/src/pathops/SkPathOpsCubic.cpp | 489 +- libskia/src/pathops/SkPathOpsCubic.h | 156 +- libskia/src/pathops/SkPathOpsCurve.cpp | 145 + libskia/src/pathops/SkPathOpsCurve.h | 367 +- libskia/src/pathops/SkPathOpsDebug.cpp | 3080 ++++++++++- libskia/src/pathops/SkPathOpsDebug.h | 348 +- libskia/src/pathops/SkPathOpsLine.cpp | 70 +- libskia/src/pathops/SkPathOpsLine.h | 23 +- libskia/src/pathops/SkPathOpsOp.cpp | 423 +- libskia/src/pathops/SkPathOpsPoint.cpp | 5 - libskia/src/pathops/SkPathOpsPoint.h | 132 +- libskia/src/pathops/SkPathOpsQuad.cpp | 241 +- libskia/src/pathops/SkPathOpsQuad.h | 82 +- libskia/src/pathops/SkPathOpsRect.cpp | 73 +- libskia/src/pathops/SkPathOpsRect.h | 52 +- libskia/src/pathops/SkPathOpsSimplify.cpp | 269 +- libskia/src/pathops/SkPathOpsTSect.cpp | 62 + libskia/src/pathops/SkPathOpsTSect.h | 2408 +++++++++ libskia/src/pathops/SkPathOpsTightBounds.cpp | 83 + libskia/src/pathops/SkPathOpsTriangle.cpp | 51 - libskia/src/pathops/SkPathOpsTriangle.h | 20 - libskia/src/pathops/SkPathOpsTypes.cpp | 90 +- libskia/src/pathops/SkPathOpsTypes.h | 356 +- libskia/src/pathops/SkPathOpsWinding.cpp | 416 ++ libskia/src/pathops/SkPathWriter.cpp | 387 +- libskia/src/pathops/SkPathWriter.h | 53 +- libskia/src/pathops/SkQuarticRoot.cpp | 165 - libskia/src/pathops/SkQuarticRoot.h | 16 - libskia/src/pathops/SkReduceOrder.cpp | 50 +- libskia/src/pathops/SkReduceOrder.h | 5 +- libskia/src/pathops/main.cpp | 16 - libskia/src/pdf/SkBitmapKey.h | 77 + libskia/src/pdf/SkDeflate.cpp | 121 + libskia/src/pdf/SkDeflate.h | 53 + libskia/src/pdf/SkDocument_PDF_None.cpp | 17 + libskia/src/pdf/SkJpegInfo.cpp | 119 + libskia/src/pdf/SkJpegInfo.h | 31 + libskia/src/pdf/SkPDFBitmap.cpp | 525 ++ libskia/src/pdf/SkPDFBitmap.h | 24 + libskia/src/pdf/SkPDFCanon.cpp | 125 + libskia/src/pdf/SkPDFCanon.h | 108 + libskia/src/pdf/SkPDFCanvas.cpp | 97 + libskia/src/pdf/SkPDFCanvas.h | 56 + libskia/src/pdf/SkPDFCatalog.cpp | 215 - libskia/src/pdf/SkPDFCatalog.h | 137 - .../src/pdf/SkPDFConvertType1FontStream.cpp | 205 + libskia/src/pdf/SkPDFConvertType1FontStream.h | 28 + libskia/src/pdf/SkPDFDevice.cpp | 2529 +++++---- libskia/src/pdf/SkPDFDevice.h | 303 ++ libskia/src/pdf/SkPDFDeviceFlattener.cpp | 155 - libskia/src/pdf/SkPDFDeviceFlattener.h | 53 - libskia/src/pdf/SkPDFDocument.cpp | 658 ++- libskia/src/pdf/SkPDFDocument.h | 89 + libskia/src/pdf/SkPDFFont.cpp | 1850 ++----- libskia/src/pdf/SkPDFFont.h | 209 +- libskia/src/pdf/SkPDFFontImpl.h | 83 - libskia/src/pdf/SkPDFFormXObject.cpp | 98 +- libskia/src/pdf/SkPDFFormXObject.h | 56 +- libskia/src/pdf/SkPDFGraphicState.cpp | 399 +- libskia/src/pdf/SkPDFGraphicState.h | 99 +- libskia/src/pdf/SkPDFImage.cpp | 635 --- libskia/src/pdf/SkPDFImage.h | 98 - .../src/pdf/SkPDFMakeCIDGlyphWidthsArray.cpp | 262 + .../src/pdf/SkPDFMakeCIDGlyphWidthsArray.h | 23 + libskia/src/pdf/SkPDFMakeToUnicodeCmap.cpp | 225 + libskia/src/pdf/SkPDFMakeToUnicodeCmap.h | 29 + libskia/src/pdf/SkPDFMetadata.cpp | 329 ++ libskia/src/pdf/SkPDFMetadata.h | 30 + libskia/src/pdf/SkPDFPage.cpp | 158 - libskia/src/pdf/SkPDFPage.h | 109 - libskia/src/pdf/SkPDFResourceDict.cpp | 120 +- libskia/src/pdf/SkPDFResourceDict.h | 71 +- libskia/src/pdf/SkPDFShader.cpp | 1374 ++--- libskia/src/pdf/SkPDFShader.h | 81 +- libskia/src/pdf/SkPDFStream.cpp | 125 - libskia/src/pdf/SkPDFStream.h | 100 - libskia/src/pdf/SkPDFTypes.cpp | 852 +-- libskia/src/pdf/SkPDFTypes.h | 578 +- libskia/src/pdf/SkPDFUtils.cpp | 349 +- libskia/src/pdf/SkPDFUtils.h | 98 +- libskia/src/pdf/SkScopeExit.h | 50 + libskia/src/pdf/SkTSet.h | 356 -- libskia/src/pipe/SkGPipePriv.h | 286 - libskia/src/pipe/SkGPipeRead.cpp | 896 ---- libskia/src/pipe/SkGPipeWrite.cpp | 1242 ----- libskia/src/pipe/SkPipeCanvas.cpp | 1062 ++++ libskia/src/pipe/SkPipeCanvas.h | 172 + libskia/src/pipe/SkPipeFormat.h | 220 + libskia/src/pipe/SkPipeReader.cpp | 966 ++++ libskia/src/pipe/SkRefSet.h | 40 + .../src/pipe/utils/SamplePipeControllers.cpp | 118 - .../src/pipe/utils/SamplePipeControllers.h | 87 - libskia/src/ports/SkAtomics_android.h | 46 - libskia/src/ports/SkAtomics_none.h | 43 - libskia/src/ports/SkAtomics_sync.h | 49 - libskia/src/ports/SkAtomics_win.h | 60 - libskia/src/ports/SkDebug_android.cpp | 32 +- libskia/src/ports/SkDebug_nacl.cpp | 38 - libskia/src/ports/SkDebug_stdio.cpp | 4 +- libskia/src/ports/SkDebug_win.cpp | 17 +- .../src/ports/SkDiscardableMemory_ashmem.cpp | 113 - .../src/ports/SkDiscardableMemory_none.cpp | 1 + libskia/src/ports/SkFontConfigInterface.cpp | 30 + .../ports/SkFontConfigInterface_android.cpp | 921 ---- .../ports/SkFontConfigInterface_direct.cpp | 571 +- .../src/ports/SkFontConfigInterface_direct.h | 38 + .../SkFontConfigInterface_direct_factory.cpp | 16 + .../src/ports/SkFontConfigParser_android.cpp | 412 -- .../src/ports/SkFontConfigParser_android.h | 61 - libskia/src/ports/SkFontConfigTypeface.h | 66 +- libskia/src/ports/SkFontHost_FreeType.cpp | 1506 +++--- .../src/ports/SkFontHost_FreeType_common.cpp | 197 +- .../src/ports/SkFontHost_FreeType_common.h | 92 +- libskia/src/ports/SkFontHost_android.cpp | 1238 ----- libskia/src/ports/SkFontHost_fontconfig.cpp | 212 - libskia/src/ports/SkFontHost_linux.cpp | 413 -- libskia/src/ports/SkFontHost_mac.cpp | 1598 +++--- libskia/src/ports/SkFontHost_win.cpp | 809 ++- libskia/src/ports/SkFontHost_win_dw.cpp | 1912 ------- .../ports/SkFontMgr_FontConfigInterface.cpp | 302 ++ .../SkFontMgr_FontConfigInterface_factory.cpp | 18 + libskia/src/ports/SkFontMgr_android.cpp | 550 ++ .../src/ports/SkFontMgr_android_factory.cpp | 48 + .../src/ports/SkFontMgr_android_parser.cpp | 801 +++ libskia/src/ports/SkFontMgr_android_parser.h | 213 + libskia/src/ports/SkFontMgr_custom.cpp | 523 ++ .../SkFontMgr_custom_directory_factory.cpp | 17 + .../SkFontMgr_custom_embedded_factory.cpp | 17 + .../ports/SkFontMgr_custom_empty_factory.cpp | 13 + libskia/src/ports/SkFontMgr_default_dw.cpp | 6 - libskia/src/ports/SkFontMgr_default_gdi.cpp | 6 - ...t_none.cpp => SkFontMgr_empty_factory.cpp} | 6 +- libskia/src/ports/SkFontMgr_fontconfig.cpp | 958 ++++ .../ports/SkFontMgr_fontconfig_factory.cpp | 14 + libskia/src/ports/SkFontMgr_win_dw.cpp | 1095 ++++ .../src/ports/SkFontMgr_win_dw_factory.cpp | 18 + .../src/ports/SkFontMgr_win_gdi_factory.cpp | 18 + .../ports/SkGlobalInitialization_chromium.cpp | 120 - .../ports/SkGlobalInitialization_default.cpp | 144 +- libskia/src/ports/SkHarfBuzzFont.cpp | 182 - libskia/src/ports/SkImageDecoder_CG.cpp | 306 -- libskia/src/ports/SkImageDecoder_WIC.cpp | 464 -- libskia/src/ports/SkImageDecoder_empty.cpp | 155 - libskia/src/ports/SkImageEncoder_CG.cpp | 118 + libskia/src/ports/SkImageEncoder_WIC.cpp | 211 + .../SkImageEncoder_none.cpp} | 11 +- libskia/src/ports/SkImageGeneratorCG.cpp | 122 + libskia/src/ports/SkImageGeneratorCG.h | 43 + libskia/src/ports/SkImageGeneratorWIC.cpp | 175 + libskia/src/ports/SkImageGeneratorWIC.h | 63 + libskia/src/ports/SkImageGenerator_none.cpp | 12 + libskia/src/ports/SkImageGenerator_skia.cpp | 13 + libskia/src/ports/SkMemory_malloc.cpp | 30 +- libskia/src/ports/SkMemory_mozalloc.cpp | 11 +- libskia/src/ports/SkMutex_none.h | 34 - libskia/src/ports/SkMutex_pthread.h | 87 - libskia/src/ports/SkMutex_win.h | 76 - libskia/src/ports/SkOSFile_none.cpp | 26 - libskia/src/ports/SkOSFile_posix.cpp | 127 +- libskia/src/ports/SkOSFile_stdio.cpp | 134 +- libskia/src/ports/SkOSFile_win.cpp | 178 +- libskia/src/ports/SkOSLibrary.h | 14 + libskia/src/ports/SkOSLibrary_posix.cpp | 25 + libskia/src/ports/SkOSLibrary_win.cpp | 21 + .../ports/SkPurgeableMemoryBlock_android.cpp | 110 - .../src/ports/SkPurgeableMemoryBlock_mac.cpp | 104 - .../src/ports/SkPurgeableMemoryBlock_none.cpp | 40 - .../src/ports/SkRemotableFontMgr_win_dw.cpp | 490 ++ libskia/src/ports/SkScalerContext_win_dw.cpp | 918 ++++ libskia/src/ports/SkScalerContext_win_dw.h | 89 + libskia/src/ports/SkTLS_none.cpp | 2 +- libskia/src/ports/SkTLS_pthread.cpp | 15 +- libskia/src/ports/SkTLS_win.cpp | 13 +- libskia/src/ports/SkTime_Unix.cpp | 39 - libskia/src/ports/SkTime_win.cpp | 38 - libskia/src/ports/SkTypeface_win_dw.cpp | 417 ++ libskia/src/ports/SkTypeface_win_dw.h | 121 + libskia/src/ports/SkXMLParser_empty.cpp | 23 - libskia/src/ports/SkXMLParser_expat.cpp | 140 - libskia/src/ports/SkXMLParser_tinyxml.cpp | 87 - libskia/src/ports/SkXMLPullParser_expat.cpp | 213 - libskia/src/ports/android-cpu-features.c | 3 + libskia/src/sfnt/SkIBMFamilyClass.h | 242 +- libskia/src/sfnt/SkOTTableTypes.h | 14 + libskia/src/sfnt/SkOTTable_EBDT.h | 108 + libskia/src/sfnt/SkOTTable_EBLC.h | 150 + libskia/src/sfnt/SkOTTable_EBSC.h | 41 + libskia/src/sfnt/SkOTTable_OS_2.h | 22 +- libskia/src/sfnt/SkOTTable_OS_2_V0.h | 71 +- libskia/src/sfnt/SkOTTable_OS_2_V1.h | 273 +- libskia/src/sfnt/SkOTTable_OS_2_V2.h | 300 +- libskia/src/sfnt/SkOTTable_OS_2_V3.h | 317 +- libskia/src/sfnt/SkOTTable_OS_2_V4.h | 395 +- libskia/src/sfnt/SkOTTable_OS_2_VA.h | 67 +- libskia/src/sfnt/SkOTTable_gasp.h | 72 + libskia/src/sfnt/SkOTTable_glyf.h | 1 - libskia/src/sfnt/SkOTTable_head.h | 36 +- libskia/src/sfnt/SkOTTable_hhea.h | 12 +- libskia/src/sfnt/SkOTTable_maxp_CFF.h | 4 +- libskia/src/sfnt/SkOTTable_maxp_TT.h | 15 +- libskia/src/sfnt/SkOTTable_name.cpp | 4 +- libskia/src/sfnt/SkOTTable_name.h | 853 ++- libskia/src/sfnt/SkOTTable_post.h | 20 +- libskia/src/sfnt/SkOTUtils.cpp | 40 +- libskia/src/sfnt/SkOTUtils.h | 14 +- libskia/src/sfnt/SkPanose.h | 942 ++-- libskia/src/sfnt/SkPreprocessorSeq.h | 826 --- libskia/src/sfnt/SkSFNTHeader.h | 4 +- libskia/src/sfnt/SkTTCFHeader.h | 2 +- libskia/src/sfnt/SkTypedEnum.h | 68 - libskia/src/sksl/GLSL.std.450.h | 131 + libskia/src/sksl/SkSLCFGGenerator.cpp | 343 ++ libskia/src/sksl/SkSLCFGGenerator.h | 90 + libskia/src/sksl/SkSLCodeGenerator.h | 28 + libskia/src/sksl/SkSLCompiler.cpp | 505 ++ libskia/src/sksl/SkSLCompiler.h | 86 + libskia/src/sksl/SkSLContext.h | 285 + libskia/src/sksl/SkSLErrorReporter.h | 31 + libskia/src/sksl/SkSLGLSLCodeGenerator.cpp | 749 +++ libskia/src/sksl/SkSLGLSLCodeGenerator.h | 178 + libskia/src/sksl/SkSLIRGenerator.cpp | 1496 ++++++ libskia/src/sksl/SkSLIRGenerator.h | 168 + libskia/src/sksl/SkSLMain.cpp | 66 + libskia/src/sksl/SkSLMemoryLayout.h | 128 + libskia/src/sksl/SkSLParser.cpp | 1540 ++++++ libskia/src/sksl/SkSLParser.h | 215 + libskia/src/sksl/SkSLPosition.h | 38 + libskia/src/sksl/SkSLSPIRVCodeGenerator.cpp | 2758 ++++++++++ libskia/src/sksl/SkSLSPIRVCodeGenerator.h | 275 + libskia/src/sksl/SkSLToken.h | 171 + libskia/src/sksl/SkSLUtil.cpp | 118 + libskia/src/sksl/SkSLUtil.h | 142 + .../src/sksl/ast/SkSLASTBinaryExpression.h | 41 + libskia/src/sksl/ast/SkSLASTBlock.h | 40 + libskia/src/sksl/ast/SkSLASTBoolLiteral.h | 34 + libskia/src/sksl/ast/SkSLASTBreakStatement.h | 31 + libskia/src/sksl/ast/SkSLASTCallSuffix.h | 43 + .../src/sksl/ast/SkSLASTContinueStatement.h | 31 + libskia/src/sksl/ast/SkSLASTDeclaration.h | 39 + .../src/sksl/ast/SkSLASTDiscardStatement.h | 31 + libskia/src/sksl/ast/SkSLASTDoStatement.h | 37 + libskia/src/sksl/ast/SkSLASTExpression.h | 41 + .../src/sksl/ast/SkSLASTExpressionStatement.h | 34 + libskia/src/sksl/ast/SkSLASTExtension.h | 34 + libskia/src/sksl/ast/SkSLASTFieldSuffix.h | 35 + libskia/src/sksl/ast/SkSLASTFloatLiteral.h | 34 + libskia/src/sksl/ast/SkSLASTForStatement.h | 56 + libskia/src/sksl/ast/SkSLASTFunction.h | 57 + libskia/src/sksl/ast/SkSLASTIdentifier.h | 34 + libskia/src/sksl/ast/SkSLASTIfStatement.h | 47 + libskia/src/sksl/ast/SkSLASTIndexSuffix.h | 45 + libskia/src/sksl/ast/SkSLASTIntLiteral.h | 35 + libskia/src/sksl/ast/SkSLASTInterfaceBlock.h | 59 + .../sksl/ast/SkSLASTModifiersDeclaration.h | 37 + libskia/src/sksl/ast/SkSLASTNode.h | 27 + libskia/src/sksl/ast/SkSLASTParameter.h | 48 + libskia/src/sksl/ast/SkSLASTPositionNode.h | 28 + libskia/src/sksl/ast/SkSLASTPrecision.h | 45 + .../src/sksl/ast/SkSLASTPrefixExpression.h | 37 + libskia/src/sksl/ast/SkSLASTReturnStatement.h | 39 + libskia/src/sksl/ast/SkSLASTStatement.h | 46 + libskia/src/sksl/ast/SkSLASTSuffix.h | 51 + .../src/sksl/ast/SkSLASTSuffixExpression.h | 37 + .../src/sksl/ast/SkSLASTTernaryExpression.h | 41 + libskia/src/sksl/ast/SkSLASTType.h | 40 + libskia/src/sksl/ast/SkSLASTVarDeclaration.h | 88 + .../sksl/ast/SkSLASTVarDeclarationStatement.h | 35 + libskia/src/sksl/ast/SkSLASTWhileStatement.h | 37 + libskia/src/sksl/ir/SkSLBinaryExpression.h | 41 + libskia/src/sksl/ir/SkSLBlock.h | 44 + libskia/src/sksl/ir/SkSLBoolLiteral.h | 39 + libskia/src/sksl/ir/SkSLBreakStatement.h | 32 + libskia/src/sksl/ir/SkSLConstructor.h | 52 + libskia/src/sksl/ir/SkSLContinueStatement.h | 32 + libskia/src/sksl/ir/SkSLDiscardStatement.h | 32 + libskia/src/sksl/ir/SkSLDoStatement.h | 38 + libskia/src/sksl/ir/SkSLExpression.h | 56 + libskia/src/sksl/ir/SkSLExpressionStatement.h | 35 + libskia/src/sksl/ir/SkSLExtension.h | 34 + libskia/src/sksl/ir/SkSLField.h | 41 + libskia/src/sksl/ir/SkSLFieldAccess.h | 47 + libskia/src/sksl/ir/SkSLFloatLiteral.h | 39 + libskia/src/sksl/ir/SkSLForStatement.h | 59 + libskia/src/sksl/ir/SkSLFunctionCall.h | 46 + libskia/src/sksl/ir/SkSLFunctionDeclaration.h | 113 + libskia/src/sksl/ir/SkSLFunctionDefinition.h | 39 + libskia/src/sksl/ir/SkSLFunctionReference.h | 38 + libskia/src/sksl/ir/SkSLIRNode.h | 32 + libskia/src/sksl/ir/SkSLIfStatement.h | 44 + libskia/src/sksl/ir/SkSLIndexExpression.h | 66 + libskia/src/sksl/ir/SkSLIntLiteral.h | 40 + libskia/src/sksl/ir/SkSLInterfaceBlock.h | 51 + libskia/src/sksl/ir/SkSLLayout.h | 205 + libskia/src/sksl/ir/SkSLModifiers.h | 109 + .../src/sksl/ir/SkSLModifiersDeclaration.h | 37 + libskia/src/sksl/ir/SkSLPostfixExpression.h | 36 + libskia/src/sksl/ir/SkSLPrefixExpression.h | 36 + libskia/src/sksl/ir/SkSLProgram.h | 47 + libskia/src/sksl/ir/SkSLProgramElement.h | 38 + libskia/src/sksl/ir/SkSLReturnStatement.h | 42 + libskia/src/sksl/ir/SkSLStatement.h | 45 + libskia/src/sksl/ir/SkSLSwizzle.h | 87 + libskia/src/sksl/ir/SkSLSymbol.h | 40 + libskia/src/sksl/ir/SkSLSymbolTable.cpp | 118 + libskia/src/sksl/ir/SkSLSymbolTable.h | 58 + libskia/src/sksl/ir/SkSLTernaryExpression.h | 43 + libskia/src/sksl/ir/SkSLType.cpp | 135 + libskia/src/sksl/ir/SkSLType.h | 266 + libskia/src/sksl/ir/SkSLTypeReference.h | 36 + libskia/src/sksl/ir/SkSLUnresolvedFunction.h | 40 + libskia/src/sksl/ir/SkSLVarDeclarations.h | 82 + .../sksl/ir/SkSLVarDeclarationsStatement.h | 35 + libskia/src/sksl/ir/SkSLVariable.h | 55 + libskia/src/sksl/ir/SkSLVariableReference.h | 38 + libskia/src/sksl/ir/SkSLWhileStatement.h | 38 + libskia/src/sksl/lex.sksl.c | 2611 +++++++++ libskia/src/sksl/readme | 49 + libskia/src/sksl/sksl.include | 533 ++ libskia/src/sksl/sksl_frag.include | 20 + libskia/src/sksl/sksl_vert.include | 11 + libskia/src/sksl/spirv.h | 870 +++ libskia/src/svg/SkSVG.cpp | 28 - libskia/src/svg/SkSVGCanvas.cpp | 18 + libskia/src/svg/SkSVGCircle.cpp | 45 - libskia/src/svg/SkSVGCircle.h | 24 - libskia/src/svg/SkSVGClipPath.cpp | 40 - libskia/src/svg/SkSVGClipPath.h | 23 - libskia/src/svg/SkSVGDefs.h | 23 - libskia/src/svg/SkSVGDevice.cpp | 817 +++ libskia/src/svg/SkSVGDevice.h | 73 + libskia/src/svg/SkSVGElements.cpp | 86 - libskia/src/svg/SkSVGElements.h | 73 - libskia/src/svg/SkSVGEllipse.cpp | 47 - libskia/src/svg/SkSVGEllipse.h | 25 - libskia/src/svg/SkSVGFeColorMatrix.cpp | 24 - libskia/src/svg/SkSVGFeColorMatrix.h | 26 - libskia/src/svg/SkSVGFilter.cpp | 25 - libskia/src/svg/SkSVGFilter.h | 27 - libskia/src/svg/SkSVGG.h | 21 - libskia/src/svg/SkSVGGradient.cpp | 114 - libskia/src/svg/SkSVGGradient.h | 29 - libskia/src/svg/SkSVGGroup.cpp | 45 - libskia/src/svg/SkSVGGroup.h | 28 - libskia/src/svg/SkSVGImage.cpp | 44 - libskia/src/svg/SkSVGImage.h | 28 - libskia/src/svg/SkSVGLine.cpp | 30 - libskia/src/svg/SkSVGLine.h | 25 - libskia/src/svg/SkSVGLinearGradient.cpp | 44 - libskia/src/svg/SkSVGLinearGradient.h | 28 - libskia/src/svg/SkSVGMask.cpp | 33 - libskia/src/svg/SkSVGMask.h | 29 - libskia/src/svg/SkSVGMetadata.cpp | 24 - libskia/src/svg/SkSVGMetadata.h | 23 - libskia/src/svg/SkSVGPaintState.cpp | 454 -- libskia/src/svg/SkSVGParser.cpp | 441 -- libskia/src/svg/SkSVGPath.cpp | 37 - libskia/src/svg/SkSVGPath.h | 22 - libskia/src/svg/SkSVGPolygon.cpp | 33 - libskia/src/svg/SkSVGPolygon.h | 23 - libskia/src/svg/SkSVGPolyline.cpp | 43 - libskia/src/svg/SkSVGPolyline.h | 27 - libskia/src/svg/SkSVGRadialGradient.cpp | 42 - libskia/src/svg/SkSVGRadialGradient.h | 30 - libskia/src/svg/SkSVGRect.cpp | 35 - libskia/src/svg/SkSVGRect.h | 26 - libskia/src/svg/SkSVGSVG.cpp | 76 - libskia/src/svg/SkSVGSVG.h | 34 - libskia/src/svg/SkSVGStop.cpp | 24 - libskia/src/svg/SkSVGStop.h | 23 - libskia/src/svg/SkSVGSymbol.cpp | 22 - libskia/src/svg/SkSVGSymbol.h | 22 - libskia/src/svg/SkSVGText.cpp | 39 - libskia/src/svg/SkSVGText.h | 32 - libskia/src/svg/SkSVGUse.cpp | 30 - libskia/src/svg/SkSVGUse.h | 28 - libskia/src/text/SkTextLayout.cpp | 78 - libskia/src/utils/SkBase64.cpp | 30 +- libskia/src/utils/SkBase64.h | 7 +- libskia/src/utils/SkBitSet.cpp | 83 - libskia/src/utils/SkBitSet.h | 70 +- libskia/src/utils/SkBitmapHasher.cpp | 64 - libskia/src/utils/SkBitmapHasher.h | 35 - .../src/utils/SkBitmapSourceDeserializer.cpp | 31 + .../src/utils/SkBitmapSourceDeserializer.h | 21 + libskia/src/utils/SkBoundaryPatch.cpp | 5 +- libskia/src/utils/SkCamera.cpp | 54 +- libskia/src/utils/SkCanvasStack.cpp | 33 +- libskia/src/utils/SkCanvasStack.h | 29 +- libskia/src/utils/SkCanvasStateUtils.cpp | 202 +- libskia/src/utils/SkCondVar.cpp | 68 - libskia/src/utils/SkCountdown.cpp | 32 - libskia/src/utils/SkCubicInterval.cpp | 67 - libskia/src/utils/SkCullPoints.cpp | 219 - libskia/src/utils/SkCurveMeasure.cpp | 319 ++ libskia/src/utils/SkCurveMeasure.h | 76 + libskia/src/utils/SkDashPath.cpp | 345 ++ libskia/src/utils/SkDashPathPriv.h | 52 + libskia/src/utils/SkDebugTrace.h | 24 - libskia/src/utils/SkDeferredCanvas.cpp | 1298 ++--- libskia/src/utils/SkDeferredCanvas.h | 156 + libskia/src/utils/SkDumpCanvas.cpp | 325 +- libskia/src/utils/SkEventTracer.cpp | 60 + libskia/src/utils/SkFrontBufferedStream.cpp | 83 +- libskia/src/utils/SkInterpolator.cpp | 85 +- libskia/src/utils/SkJSON.cpp | 634 --- libskia/src/utils/SkLayer.cpp | 17 +- libskia/src/utils/SkLua.cpp | 1118 +++- libskia/src/utils/SkLuaCanvas.cpp | 220 +- libskia/src/utils/SkMD5.h | 53 - libskia/src/utils/SkMatrix22.cpp | 40 + libskia/src/utils/SkMatrix22.h | 31 + libskia/src/utils/SkMeshUtils.cpp | 15 +- libskia/src/utils/SkMultiPictureDocument.cpp | 91 + libskia/src/utils/SkMultiPictureDocument.h | 48 + .../src/utils/SkMultiPictureDocumentPriv.h | 32 + .../utils/SkMultiPictureDocumentReader.cpp | 93 + .../src/utils/SkMultiPictureDocumentReader.h | 46 + libskia/src/utils/SkNWayCanvas.cpp | 227 +- libskia/src/utils/SkNinePatch.cpp | 335 -- libskia/src/utils/SkNullCanvas.cpp | 6 +- libskia/src/utils/SkOSFile.cpp | 249 - libskia/src/utils/SkOSPath.cpp | 45 + libskia/src/utils/SkOSPath.h | 55 + libskia/src/utils/SkPDFRasterizer.cpp | 82 - libskia/src/utils/SkPDFRasterizer.h | 19 - libskia/src/utils/SkPaintFilterCanvas.cpp | 228 + libskia/src/utils/SkParse.cpp | 21 +- libskia/src/utils/SkParseColor.cpp | 23 +- libskia/src/utils/SkParsePath.cpp | 70 +- libskia/src/utils/SkPatchGrid.cpp | 189 + libskia/src/utils/SkPatchGrid.h | 142 + libskia/src/utils/SkPatchUtils.cpp | 311 ++ libskia/src/utils/SkPatchUtils.h | 121 + libskia/src/utils/SkPathUtils.cpp | 152 - libskia/src/utils/SkPictureUtils.cpp | 268 - libskia/src/utils/SkProxyCanvas.cpp | 180 - libskia/src/utils/SkRGBAToYUV.cpp | 58 + libskia/src/utils/SkRGBAToYUV.h | 21 + libskia/src/utils/SkRTConf.cpp | 325 -- libskia/src/utils/SkSHA1.cpp | 268 - libskia/src/utils/SkSHA1.h | 53 - .../src/utils/SkShadowPaintFilterCanvas.cpp | 307 ++ libskia/src/utils/SkShadowPaintFilterCanvas.h | 117 + libskia/src/utils/SkTFitsIn.h | 209 - libskia/src/utils/SkTLogic.h | 61 - libskia/src/utils/SkTextBox.cpp | 302 ++ libskia/src/utils/SkTextureCompressor.cpp | 231 + libskia/src/utils/SkTextureCompressor.h | 110 + .../src/utils/SkTextureCompressor_ASTC.cpp | 2100 ++++++++ libskia/src/utils/SkTextureCompressor_ASTC.h | 27 + .../src/utils/SkTextureCompressor_Blitter.h | 733 +++ .../src/utils/SkTextureCompressor_LATC.cpp | 518 ++ libskia/src/utils/SkTextureCompressor_LATC.h | 26 + .../src/utils/SkTextureCompressor_R11EAC.cpp | 669 +++ .../src/utils/SkTextureCompressor_R11EAC.h | 26 + libskia/src/utils/SkTextureCompressor_Utils.h | 68 + libskia/src/utils/SkThreadPool.cpp | 127 - libskia/src/utils/SkThreadUtils.h | 9 +- libskia/src/utils/SkThreadUtils_pthread.cpp | 10 +- .../src/utils/SkThreadUtils_pthread_linux.cpp | 46 - .../src/utils/SkThreadUtils_pthread_mach.cpp | 30 - .../src/utils/SkThreadUtils_pthread_other.cpp | 12 - libskia/src/utils/SkThreadUtils_win.cpp | 59 +- libskia/src/utils/SkThreadUtils_win.h | 3 +- libskia/src/utils/SkUnitMappers.cpp | 60 - libskia/src/utils/SkWhitelistChecksums.inc | 50 + libskia/src/utils/SkWhitelistTypefaces.cpp | 273 + libskia/src/utils/android/ashmem.cpp | 87 - libskia/src/utils/android/ashmem.h | 50 - libskia/src/utils/debugger/SkDebugCanvas.cpp | 477 -- libskia/src/utils/debugger/SkDebugCanvas.h | 275 - libskia/src/utils/debugger/SkDrawCommand.cpp | 899 ---- libskia/src/utils/debugger/SkDrawCommand.h | 560 -- libskia/src/utils/debugger/SkObjectParser.cpp | 372 -- libskia/src/utils/debugger/SkObjectParser.h | 128 - libskia/src/utils/ios/SkFontHost_iOS.mm | 262 - libskia/src/utils/ios/SkImageDecoder_iOS.mm | 68 - libskia/src/utils/ios/SkOSFile_iOS.mm | 98 - libskia/src/utils/ios/SkStream_NSData.mm | 44 - libskia/src/utils/mac/SkCreateCGImageRef.cpp | 219 +- libskia/src/utils/mac/SkStream_mac.cpp | 38 +- libskia/src/utils/win/SkAutoCoInitialize.cpp | 13 +- .../utils/win/SkAutoCoInitialize.h | 13 +- libskia/src/utils/win/SkDWrite.cpp | 128 + libskia/src/utils/win/SkDWrite.h | 107 + .../src/utils/win/SkDWriteFontFileStream.cpp | 49 +- .../src/utils/win/SkDWriteFontFileStream.h | 29 +- .../src/utils/win/SkDWriteGeometrySink.cpp | 7 +- libskia/src/utils/win/SkDWriteGeometrySink.h | 22 +- libskia/src/utils/win/SkHRESULT.cpp | 28 +- .../{include => src}/utils/win/SkHRESULT.h | 22 +- libskia/src/utils/win/SkIStream.cpp | 33 +- .../{include => src}/utils/win/SkIStream.h | 18 +- .../utils/win/SkTScopedComPtr.h | 37 +- .../{include/utils => src/utils/win}/SkWGL.h | 81 +- libskia/src/utils/win/SkWGL_win.cpp | 301 +- libskia/src/views/SkEvent.cpp | 511 ++ libskia/src/views/SkEventSink.cpp | 300 ++ libskia/src/views/SkOSMenu.cpp | 263 + libskia/src/views/SkTagList.cpp | 61 + libskia/src/views/SkTagList.h | 42 + libskia/src/views/SkTouchGesture.cpp | 353 ++ libskia/src/views/SkView.cpp | 810 +++ libskia/src/views/SkViewPriv.cpp | 102 + libskia/src/views/SkViewPriv.h | 43 + libskia/src/views/SkWindow.cpp | 361 ++ libskia/src/views/mac/SkEventNotifier.h | 13 + libskia/src/views/mac/SkNSView.h | 50 + libskia/src/views/mac/SkOptionsTableView.h | 39 + .../mac/SkSampleNSView.h} | 10 +- libskia/src/views/mac/SkTextFieldCell.h | 14 + libskia/src/views/sdl/SkOSWindow_SDL.cpp | 401 ++ libskia/src/views/unix/SkOSWindow_Unix.cpp | 519 ++ libskia/src/views/unix/XkeysToSkKeys.h | 66 + libskia/src/views/unix/keysym2ucs.h | 14 + libskia/src/views/unix/skia_unix.cpp | 28 + libskia/src/views/win/SkOSWindow_win.cpp | 772 +++ libskia/src/views/win/skia_win.cpp | 135 + libskia/src/xml/SkDOM.cpp | 477 ++ libskia/src/xml/SkXMLParser.cpp | 214 + libskia/src/xml/SkXMLWriter.cpp | 361 ++ libskia/src/xps/SkDocument_XPS.cpp | 82 + libskia/src/xps/SkDocument_XPS_None.cpp | 17 + libskia/src/{device => }/xps/SkXPSDevice.cpp | 755 +-- .../{include/device => src}/xps/SkXPSDevice.h | 72 +- 2425 files changed, 336069 insertions(+), 164106 deletions(-) create mode 100755 libskia/git-revision.txt create mode 100644 libskia/include/android/SkBRDAllocator.h create mode 100644 libskia/include/android/SkBitmapRegionDecoder.h create mode 100644 libskia/include/animator/SkAnimator.h create mode 100644 libskia/include/animator/SkAnimatorView.h create mode 100644 libskia/include/c/sk_canvas.h create mode 100644 libskia/include/c/sk_data.h create mode 100644 libskia/include/c/sk_image.h create mode 100644 libskia/include/c/sk_maskfilter.h create mode 100644 libskia/include/c/sk_matrix.h create mode 100644 libskia/include/c/sk_paint.h create mode 100644 libskia/include/c/sk_path.h create mode 100644 libskia/include/c/sk_picture.h create mode 100644 libskia/include/c/sk_shader.h create mode 100644 libskia/include/c/sk_surface.h create mode 100644 libskia/include/c/sk_types.h create mode 100644 libskia/include/codec/SkAndroidCodec.h create mode 100644 libskia/include/codec/SkCodec.h create mode 100644 libskia/include/codec/SkEncodedInfo.h delete mode 100644 libskia/include/config/sk_stdint.h delete mode 100644 libskia/include/core/Sk64.h delete mode 100755 libskia/include/core/SkAdvancedTypefaceMetrics.h create mode 100644 libskia/include/core/SkBBHFactory.h create mode 100644 libskia/include/core/SkBlendMode.h create mode 100644 libskia/include/core/SkBlurTypes.h delete mode 100644 libskia/include/core/SkBounder.h delete mode 100644 libskia/include/core/SkChecksum.h create mode 100644 libskia/include/core/SkClipOp.h delete mode 100644 libskia/include/core/SkColorShader.h create mode 100644 libskia/include/core/SkColorSpace.h create mode 100644 libskia/include/core/SkColorSpaceXform.h delete mode 100644 libskia/include/core/SkComposeShader.h delete mode 100644 libskia/include/core/SkDeviceProperties.h create mode 100644 libskia/include/core/SkDrawable.h delete mode 100644 libskia/include/core/SkEmptyShader.h create mode 100644 libskia/include/core/SkEncodedImageFormat.h delete mode 100644 libskia/include/core/SkError.h create mode 100644 libskia/include/core/SkFilterQuality.h delete mode 100644 libskia/include/core/SkFlate.h delete mode 100644 libskia/include/core/SkFlattenableBuffers.h delete mode 100644 libskia/include/core/SkFloatingPoint.h create mode 100644 libskia/include/core/SkFont.h delete mode 100644 libskia/include/core/SkFontHost.h rename libskia/include/{ports => core}/SkFontStyle.h (70%) delete mode 100644 libskia/include/core/SkImageDecoder.h create mode 100644 libskia/include/core/SkImageDeserializer.h delete mode 100644 libskia/include/core/SkImageFilterUtils.h delete mode 100644 libskia/include/core/SkInstCnt.h create mode 100644 libskia/include/core/SkLights.h rename libskia/include/{utils => core}/SkMatrix44.h (80%) rename libskia/{src/gpu/SkGrTexturePixelRef.cpp => include/core/SkMilestone.h} (58%) create mode 100644 libskia/include/core/SkMultiPictureDraw.h delete mode 100644 libskia/include/core/SkPackBits.h delete mode 100644 libskia/include/core/SkPaintOptionsAndroid.h create mode 100644 libskia/include/core/SkPictureAnalyzer.h create mode 100644 libskia/include/core/SkPictureRecorder.h create mode 100644 libskia/include/core/SkPixelSerializer.h create mode 100644 libskia/include/core/SkPixmap.h create mode 100644 libskia/include/core/SkPngChunkReader.h create mode 100644 libskia/include/core/SkPoint3.h create mode 100644 libskia/include/core/SkRSXform.h create mode 100644 libskia/include/core/SkRWBuffer.h create mode 100644 libskia/include/core/SkSurfaceProps.h create mode 100644 libskia/include/core/SkSwizzle.h create mode 100644 libskia/include/core/SkTextBlob.h delete mode 100644 libskia/include/core/SkThread.h delete mode 100644 libskia/include/core/SkTileGridPicture.h delete mode 100644 libskia/include/core/SkTrace.h create mode 100644 libskia/include/core/SkTraceMemoryDump.h delete mode 100644 libskia/include/core/SkUnitMapper.h create mode 100644 libskia/include/core/SkWriteBuffer.h delete mode 100644 libskia/include/core/SkXfermode.h create mode 100644 libskia/include/core/SkYUVSizeInfo.h delete mode 100644 libskia/include/device/xps/SkConstexprMath.h create mode 100644 libskia/include/effects/SkAlphaThresholdFilter.h create mode 100644 libskia/include/effects/SkArcToPathEffect.h delete mode 100644 libskia/include/effects/SkAvoidXfermode.h delete mode 100644 libskia/include/effects/SkBicubicImageFilter.h delete mode 100644 libskia/include/effects/SkBitmapSource.h create mode 100644 libskia/include/effects/SkColorCubeFilter.h mode change 100755 => 100644 libskia/include/effects/SkColorFilterImageFilter.h create mode 100644 libskia/include/effects/SkGammaColorFilter.h create mode 100644 libskia/include/effects/SkGaussianEdgeShader.h create mode 100644 libskia/include/effects/SkImageSource.h delete mode 100644 libskia/include/effects/SkKernel33MaskFilter.h delete mode 100644 libskia/include/effects/SkLerpXfermode.h mode change 100755 => 100644 libskia/include/effects/SkMergeImageFilter.h create mode 100644 libskia/include/effects/SkPaintImageFilter.h delete mode 100644 libskia/include/effects/SkPixelXorXfermode.h delete mode 100644 libskia/include/effects/SkPorterDuff.h create mode 100644 libskia/include/effects/SkRRectsGaussianEdgeMaskFilter.h delete mode 100644 libskia/include/effects/SkRectShaderImageFilter.h create mode 100644 libskia/include/effects/SkShadowMaskFilter.h delete mode 100644 libskia/include/effects/SkStippleMaskFilter.h delete mode 100755 libskia/include/effects/SkTestImageFilters.h delete mode 100644 libskia/include/effects/SkTransparentShader.h delete mode 100644 libskia/include/gpu/GrBackendEffectFactory.h delete mode 100755 libskia/include/gpu/GrBitmapTextContext.h create mode 100644 libskia/include/gpu/GrBlend.h create mode 100644 libskia/include/gpu/GrBuffer.h create mode 100644 libskia/include/gpu/GrCaps.h create mode 100644 libskia/include/gpu/GrClip.h delete mode 100644 libskia/include/gpu/GrClipData.h create mode 100644 libskia/include/gpu/GrColorSpaceXform.h delete mode 100644 libskia/include/gpu/GrContextFactory.h create mode 100644 libskia/include/gpu/GrContextOptions.h delete mode 100755 libskia/include/gpu/GrDistanceFieldTextContext.h delete mode 100644 libskia/include/gpu/GrDrawEffect.h delete mode 100644 libskia/include/gpu/GrEffect.h delete mode 100644 libskia/include/gpu/GrEffectStage.h delete mode 100644 libskia/include/gpu/GrEffectUnitTest.h delete mode 100644 libskia/include/gpu/GrFontScaler.h create mode 100644 libskia/include/gpu/GrFragmentProcessor.h delete mode 100644 libskia/include/gpu/GrGlyph.h create mode 100644 libskia/include/gpu/GrGpuResource.h create mode 100644 libskia/include/gpu/GrGpuResourceRef.h create mode 100644 libskia/include/gpu/GrInvariantOutput.h delete mode 100644 libskia/include/gpu/GrKey.h delete mode 100644 libskia/include/gpu/GrPoint.h create mode 100644 libskia/include/gpu/GrProcessor.h create mode 100644 libskia/include/gpu/GrProcessorUnitTest.h create mode 100644 libskia/include/gpu/GrProgramElement.h create mode 100644 libskia/include/gpu/GrRenderTargetContext.h delete mode 100644 libskia/include/gpu/GrResource.h create mode 100644 libskia/include/gpu/GrResourceKey.h create mode 100644 libskia/include/gpu/GrSamplerParams.h create mode 100644 libskia/include/gpu/GrShaderCaps.h create mode 100644 libskia/include/gpu/GrShaderVar.h create mode 100644 libskia/include/gpu/GrSurfaceContext.h delete mode 100644 libskia/include/gpu/GrTBackendEffectFactory.h create mode 100644 libskia/include/gpu/GrTestUtils.h delete mode 100644 libskia/include/gpu/GrTextContext.h delete mode 100644 libskia/include/gpu/GrTextureAccess.h create mode 100644 libskia/include/gpu/GrTextureContext.h create mode 100644 libskia/include/gpu/GrTextureProvider.h delete mode 100644 libskia/include/gpu/GrUserConfig.h create mode 100644 libskia/include/gpu/GrXferProcessor.h delete mode 100644 libskia/include/gpu/SkGpuDevice.h delete mode 100644 libskia/include/gpu/SkGrPixelRef.h delete mode 100644 libskia/include/gpu/SkGrTexturePixelRef.h create mode 100644 libskia/include/gpu/effects/GrConstColorProcessor.h create mode 100644 libskia/include/gpu/effects/GrCoverageSetOpXP.h create mode 100644 libskia/include/gpu/effects/GrCustomXfermode.h create mode 100644 libskia/include/gpu/effects/GrPorterDuffXferProcessor.h create mode 100644 libskia/include/gpu/effects/GrXfermodeFragmentProcessor.h create mode 100644 libskia/include/gpu/gl/GrGLAssembleInterface.h create mode 100644 libskia/include/gpu/gl/GrGLSLPrettyPrint.h create mode 100644 libskia/include/gpu/gl/GrGLTypes.h delete mode 100644 libskia/include/gpu/gl/SkANGLEGLContext.h delete mode 100644 libskia/include/gpu/gl/SkDebugGLContext.h delete mode 100644 libskia/include/gpu/gl/SkGLContextHelper.h delete mode 100644 libskia/include/gpu/gl/SkMesaGLContext.h delete mode 100644 libskia/include/gpu/gl/SkNativeGLContext.h delete mode 100644 libskia/include/gpu/gl/SkNullGLContext.h create mode 100644 libskia/include/gpu/vk/GrVkBackendContext.h create mode 100644 libskia/include/gpu/vk/GrVkDefines.h create mode 100644 libskia/include/gpu/vk/GrVkInterface.h create mode 100644 libskia/include/gpu/vk/GrVkTypes.h delete mode 100644 libskia/include/images/SkImageRef.h delete mode 100644 libskia/include/images/SkImageRef_GlobalPool.h delete mode 100644 libskia/include/images/SkImages.h delete mode 100644 libskia/include/images/SkMovie.h delete mode 100644 libskia/include/images/SkPageFlipper.h delete mode 100644 libskia/include/pdf/SkPDFDevice.h delete mode 100644 libskia/include/pdf/SkPDFDocument.h delete mode 100644 libskia/include/pipe/SkGPipe.h create mode 100644 libskia/include/ports/SkFontMgr_FontConfigInterface.h create mode 100644 libskia/include/ports/SkFontMgr_android.h create mode 100644 libskia/include/ports/SkFontMgr_custom.h create mode 100644 libskia/include/ports/SkFontMgr_fontconfig.h create mode 100644 libskia/include/ports/SkFontMgr_indirect.h delete mode 100644 libskia/include/ports/SkHarfBuzzFont.h create mode 100644 libskia/include/ports/SkRemotableFontMgr.h delete mode 100644 libskia/include/ports/SkTypeface_android.h create mode 100644 libskia/include/private/GrAuditTrail.h rename libskia/{src/gpu/gl => include/private}/GrGLSL.h (79%) rename libskia/{src/gpu/gl => include/private}/GrGLSL_impl.h (100%) create mode 100644 libskia/include/private/GrInstancedPipelineInfo.h create mode 100644 libskia/include/private/GrRenderTargetProxy.h create mode 100644 libskia/include/private/GrSingleOwner.h create mode 100644 libskia/include/private/GrSurfaceProxy.h create mode 100644 libskia/include/private/GrSwizzle.h create mode 100644 libskia/include/private/GrTextureProxy.h create mode 100644 libskia/include/private/GrTextureRenderTargetProxy.h rename libskia/{src/gpu/effects => include/private}/GrTextureStripAtlas.h (77%) create mode 100644 libskia/include/private/SkAtomics.h create mode 100644 libskia/include/private/SkBitmaskEnum.h create mode 100644 libskia/include/private/SkChecksum.h rename libskia/include/{core => private}/SkChunkAlloc.h (66%) rename libskia/include/{core => private}/SkFixed.h (57%) rename libskia/include/{core => private}/SkFloatBits.h (66%) create mode 100644 libskia/include/private/SkFloatingPoint.h create mode 100644 libskia/include/private/SkLeanWindows.h create mode 100644 libskia/include/private/SkMiniRecorder.h create mode 100644 libskia/include/private/SkMutex.h create mode 100644 libskia/include/private/SkOnce.h create mode 100644 libskia/include/private/SkRecords.h create mode 100644 libskia/include/private/SkSafe_math.h create mode 100644 libskia/include/private/SkSemaphore.h create mode 100644 libskia/include/private/SkShadowParams.h create mode 100644 libskia/include/private/SkSpinlock.h rename libskia/include/{core => private}/SkTArray.h (62%) rename libskia/include/{core => private}/SkTDArray.h (70%) rename libskia/include/{core => private}/SkTDict.h (71%) create mode 100644 libskia/include/private/SkTFitsIn.h create mode 100644 libskia/include/private/SkTHash.h create mode 100644 libskia/include/private/SkTLogic.h rename libskia/include/{core => private}/SkTSearch.h (99%) rename libskia/include/{core => private}/SkTemplates.h (57%) create mode 100644 libskia/include/private/SkThreadID.h rename libskia/include/{core => private}/SkWeakRefCnt.h (74%) delete mode 100644 libskia/include/svg/SkSVGAttribute.h delete mode 100644 libskia/include/svg/SkSVGBase.h create mode 100644 libskia/include/svg/SkSVGCanvas.h delete mode 100644 libskia/include/svg/SkSVGPaintState.h delete mode 100644 libskia/include/svg/SkSVGParser.h delete mode 100644 libskia/include/svg/SkSVGTypes.h delete mode 100644 libskia/include/text/SkTextLayout.h delete mode 100644 libskia/include/utils/SkCondVar.h delete mode 100644 libskia/include/utils/SkCountdown.h delete mode 100644 libskia/include/utils/SkCubicInterval.h delete mode 100644 libskia/include/utils/SkCullPoints.h delete mode 100644 libskia/include/utils/SkDebugUtils.h delete mode 100644 libskia/include/utils/SkDeferredCanvas.h create mode 100644 libskia/include/utils/SkEventTracer.h delete mode 100644 libskia/include/utils/SkJSON.h delete mode 100644 libskia/include/utils/SkJSONCPP.h delete mode 100644 libskia/include/utils/SkNinePatch.h create mode 100644 libskia/include/utils/SkNoDrawCanvas.h create mode 100644 libskia/include/utils/SkPaintFilterCanvas.h delete mode 100644 libskia/include/utils/SkParsePaint.h delete mode 100644 libskia/include/utils/SkPathUtils.h delete mode 100644 libskia/include/utils/SkProxyCanvas.h delete mode 100644 libskia/include/utils/SkRTConf.h delete mode 100644 libskia/include/utils/SkRunnable.h create mode 100644 libskia/include/utils/SkTextBox.h delete mode 100644 libskia/include/utils/SkThreadPool.h delete mode 100644 libskia/include/utils/SkUnitMappers.h delete mode 100755 libskia/include/utils/ios/SkStream_NSData.h create mode 100644 libskia/include/views/SkApplication.h create mode 100644 libskia/include/views/SkEvent.h create mode 100644 libskia/include/views/SkEventSink.h create mode 100644 libskia/include/views/SkKey.h create mode 100644 libskia/include/views/SkOSMenu.h create mode 100644 libskia/include/views/SkOSWindow_Mac.h create mode 100644 libskia/include/views/SkOSWindow_SDL.h create mode 100644 libskia/include/views/SkOSWindow_Unix.h create mode 100644 libskia/include/views/SkOSWindow_Win.h create mode 100644 libskia/include/views/SkOSWindow_iOS.h create mode 100644 libskia/include/views/SkSystemEventTypes.h create mode 100644 libskia/include/views/SkTouchGesture.h create mode 100644 libskia/include/views/SkView.h create mode 100644 libskia/include/views/SkWindow.h create mode 100644 libskia/include/xml/SkDOM.h create mode 100644 libskia/include/xml/SkXMLParser.h create mode 100644 libskia/include/xml/SkXMLWriter.h create mode 100644 libskia/rename.sh create mode 100644 libskia/src/android/SkBitmapRegionCodec.cpp create mode 100644 libskia/src/android/SkBitmapRegionCodec.h create mode 100644 libskia/src/android/SkBitmapRegionDecoder.cpp create mode 100644 libskia/src/android/SkBitmapRegionDecoderPriv.h rename libskia/src/{svg/SkSVGDefs.cpp => animator/SkADrawable.cpp} (50%) create mode 100644 libskia/src/animator/SkADrawable.h create mode 100644 libskia/src/animator/SkAnimate.h create mode 100644 libskia/src/animator/SkAnimateActive.cpp create mode 100644 libskia/src/animator/SkAnimateActive.h create mode 100644 libskia/src/animator/SkAnimateBase.cpp create mode 100644 libskia/src/animator/SkAnimateBase.h create mode 100644 libskia/src/animator/SkAnimateField.cpp create mode 100644 libskia/src/animator/SkAnimateMaker.cpp create mode 100644 libskia/src/animator/SkAnimateMaker.h create mode 100644 libskia/src/animator/SkAnimateProperties.h create mode 100644 libskia/src/animator/SkAnimateSet.cpp create mode 100644 libskia/src/animator/SkAnimateSet.h create mode 100644 libskia/src/animator/SkAnimator.cpp create mode 100644 libskia/src/animator/SkAnimatorScript.cpp create mode 100644 libskia/src/animator/SkAnimatorScript.h create mode 100644 libskia/src/animator/SkAnimatorScript2.cpp create mode 100644 libskia/src/animator/SkAnimatorScript2.h create mode 100644 libskia/src/animator/SkBoundable.cpp create mode 100644 libskia/src/animator/SkBoundable.h create mode 100644 libskia/src/animator/SkBuildCondensedInfo.cpp create mode 100644 libskia/src/animator/SkDisplayAdd.cpp create mode 100644 libskia/src/animator/SkDisplayAdd.h create mode 100644 libskia/src/animator/SkDisplayApply.cpp create mode 100644 libskia/src/animator/SkDisplayApply.h create mode 100644 libskia/src/animator/SkDisplayBounds.cpp create mode 100644 libskia/src/animator/SkDisplayBounds.h create mode 100644 libskia/src/animator/SkDisplayEvent.cpp create mode 100644 libskia/src/animator/SkDisplayEvent.h create mode 100644 libskia/src/animator/SkDisplayEvents.cpp create mode 100644 libskia/src/animator/SkDisplayEvents.h create mode 100644 libskia/src/animator/SkDisplayInclude.cpp create mode 100644 libskia/src/animator/SkDisplayInclude.h create mode 100644 libskia/src/animator/SkDisplayInput.cpp create mode 100644 libskia/src/animator/SkDisplayInput.h create mode 100644 libskia/src/animator/SkDisplayList.cpp create mode 100644 libskia/src/animator/SkDisplayList.h create mode 100644 libskia/src/animator/SkDisplayMath.cpp create mode 100644 libskia/src/animator/SkDisplayMath.h create mode 100644 libskia/src/animator/SkDisplayMovie.cpp create mode 100644 libskia/src/animator/SkDisplayMovie.h create mode 100644 libskia/src/animator/SkDisplayNumber.cpp create mode 100644 libskia/src/animator/SkDisplayNumber.h create mode 100644 libskia/src/animator/SkDisplayPost.cpp create mode 100644 libskia/src/animator/SkDisplayPost.h create mode 100644 libskia/src/animator/SkDisplayRandom.cpp create mode 100644 libskia/src/animator/SkDisplayRandom.h create mode 100644 libskia/src/animator/SkDisplayScreenplay.cpp create mode 100644 libskia/src/animator/SkDisplayScreenplay.h create mode 100644 libskia/src/animator/SkDisplayType.cpp create mode 100644 libskia/src/animator/SkDisplayType.h create mode 100644 libskia/src/animator/SkDisplayTypes.cpp create mode 100644 libskia/src/animator/SkDisplayTypes.h create mode 100644 libskia/src/animator/SkDisplayXMLParser.cpp create mode 100644 libskia/src/animator/SkDisplayXMLParser.h create mode 100644 libskia/src/animator/SkDisplayable.cpp create mode 100644 libskia/src/animator/SkDisplayable.h create mode 100644 libskia/src/animator/SkDraw3D.cpp create mode 100644 libskia/src/animator/SkDraw3D.h create mode 100644 libskia/src/animator/SkDrawBitmap.cpp create mode 100644 libskia/src/animator/SkDrawBitmap.h create mode 100644 libskia/src/animator/SkDrawBlur.cpp create mode 100644 libskia/src/animator/SkDrawBlur.h create mode 100644 libskia/src/animator/SkDrawClip.cpp create mode 100644 libskia/src/animator/SkDrawClip.h create mode 100644 libskia/src/animator/SkDrawColor.cpp create mode 100644 libskia/src/animator/SkDrawColor.h create mode 100644 libskia/src/animator/SkDrawDash.cpp create mode 100644 libskia/src/animator/SkDrawDash.h create mode 100644 libskia/src/animator/SkDrawDiscrete.cpp create mode 100644 libskia/src/animator/SkDrawDiscrete.h create mode 100644 libskia/src/animator/SkDrawEmboss.cpp create mode 100644 libskia/src/animator/SkDrawEmboss.h create mode 100644 libskia/src/animator/SkDrawExtraPathEffect.cpp rename libskia/{include/effects => src/animator}/SkDrawExtraPathEffect.h (100%) create mode 100644 libskia/src/animator/SkDrawFull.cpp create mode 100644 libskia/src/animator/SkDrawFull.h create mode 100644 libskia/src/animator/SkDrawGradient.cpp create mode 100644 libskia/src/animator/SkDrawGradient.h create mode 100644 libskia/src/animator/SkDrawGroup.cpp create mode 100644 libskia/src/animator/SkDrawGroup.h create mode 100644 libskia/src/animator/SkDrawLine.cpp create mode 100644 libskia/src/animator/SkDrawLine.h create mode 100644 libskia/src/animator/SkDrawMatrix.cpp create mode 100644 libskia/src/animator/SkDrawMatrix.h create mode 100644 libskia/src/animator/SkDrawOval.cpp create mode 100644 libskia/src/animator/SkDrawOval.h create mode 100644 libskia/src/animator/SkDrawPaint.cpp create mode 100644 libskia/src/animator/SkDrawPaint.h create mode 100644 libskia/src/animator/SkDrawPath.cpp create mode 100644 libskia/src/animator/SkDrawPath.h create mode 100644 libskia/src/animator/SkDrawPoint.cpp create mode 100644 libskia/src/animator/SkDrawPoint.h create mode 100644 libskia/src/animator/SkDrawRectangle.cpp create mode 100644 libskia/src/animator/SkDrawRectangle.h create mode 100644 libskia/src/animator/SkDrawSaveLayer.cpp create mode 100644 libskia/src/animator/SkDrawSaveLayer.h create mode 100644 libskia/src/animator/SkDrawShader.cpp create mode 100644 libskia/src/animator/SkDrawShader.h create mode 100644 libskia/src/animator/SkDrawText.cpp create mode 100644 libskia/src/animator/SkDrawText.h create mode 100644 libskia/src/animator/SkDrawTextBox.cpp create mode 100644 libskia/src/animator/SkDrawTextBox.h create mode 100644 libskia/src/animator/SkDrawTo.cpp create mode 100644 libskia/src/animator/SkDrawTo.h create mode 100644 libskia/src/animator/SkDump.cpp create mode 100644 libskia/src/animator/SkDump.h create mode 100644 libskia/src/animator/SkExtras.h create mode 100644 libskia/src/animator/SkGetCondensedInfo.cpp create mode 100644 libskia/src/animator/SkHitClear.cpp create mode 100644 libskia/src/animator/SkHitClear.h create mode 100644 libskia/src/animator/SkHitTest.cpp create mode 100644 libskia/src/animator/SkHitTest.h create mode 100644 libskia/src/animator/SkIntArray.h create mode 100644 libskia/src/animator/SkMatrixParts.cpp create mode 100644 libskia/src/animator/SkMatrixParts.h create mode 100644 libskia/src/animator/SkMemberInfo.cpp create mode 100644 libskia/src/animator/SkMemberInfo.h create mode 100644 libskia/src/animator/SkOpArray.cpp create mode 100644 libskia/src/animator/SkOpArray.h create mode 100644 libskia/src/animator/SkOperand.h create mode 100644 libskia/src/animator/SkOperand2.h create mode 100644 libskia/src/animator/SkOperandInterpolator.h create mode 100644 libskia/src/animator/SkOperandIterpolator.cpp create mode 100644 libskia/src/animator/SkPaintPart.cpp create mode 100644 libskia/src/animator/SkPaintPart.h create mode 100644 libskia/src/animator/SkParseSVGPath.cpp create mode 100644 libskia/src/animator/SkPathParts.cpp create mode 100644 libskia/src/animator/SkPathParts.h create mode 100644 libskia/src/animator/SkPostParts.cpp create mode 100644 libskia/src/animator/SkPostParts.h create mode 100644 libskia/src/animator/SkScript.cpp create mode 100644 libskia/src/animator/SkScript.h create mode 100644 libskia/src/animator/SkScript2.h create mode 100644 libskia/src/animator/SkScriptCallBack.h create mode 100644 libskia/src/animator/SkScriptDecompile.cpp create mode 100644 libskia/src/animator/SkScriptRuntime.cpp create mode 100644 libskia/src/animator/SkScriptRuntime.h create mode 100644 libskia/src/animator/SkScriptTokenizer.cpp create mode 100644 libskia/src/animator/SkSnapshot.cpp create mode 100644 libskia/src/animator/SkSnapshot.h create mode 100644 libskia/src/animator/SkTDArray_Experimental.h rename libskia/{include/core => src/animator}/SkTDStack.h (100%) create mode 100644 libskia/src/animator/SkTextOnPath.cpp create mode 100644 libskia/src/animator/SkTextOnPath.h create mode 100644 libskia/src/animator/SkTextToPath.cpp create mode 100644 libskia/src/animator/SkTextToPath.h create mode 100644 libskia/src/animator/SkTypedArray.cpp create mode 100644 libskia/src/animator/SkTypedArray.h create mode 100644 libskia/src/animator/SkXMLAnimatorWriter.cpp create mode 100644 libskia/src/animator/SkXMLAnimatorWriter.h create mode 100644 libskia/src/c/sk_c_from_to.h create mode 100644 libskia/src/c/sk_paint.cpp create mode 100644 libskia/src/c/sk_surface.cpp create mode 100644 libskia/src/c/sk_types_priv.h create mode 100644 libskia/src/codec/SkAndroidCodec.cpp create mode 100644 libskia/src/codec/SkBmpCodec.cpp create mode 100644 libskia/src/codec/SkBmpCodec.h create mode 100644 libskia/src/codec/SkBmpMaskCodec.cpp create mode 100644 libskia/src/codec/SkBmpMaskCodec.h create mode 100644 libskia/src/codec/SkBmpRLECodec.cpp create mode 100644 libskia/src/codec/SkBmpRLECodec.h create mode 100644 libskia/src/codec/SkBmpStandardCodec.cpp create mode 100644 libskia/src/codec/SkBmpStandardCodec.h create mode 100644 libskia/src/codec/SkCodec.cpp create mode 100644 libskia/src/codec/SkCodecAnimation.h create mode 100644 libskia/src/codec/SkCodecImageGenerator.cpp create mode 100644 libskia/src/codec/SkCodecImageGenerator.h create mode 100644 libskia/src/codec/SkCodecPriv.h create mode 100644 libskia/src/codec/SkGifCodec.cpp create mode 100644 libskia/src/codec/SkGifCodec.h create mode 100644 libskia/src/codec/SkIcoCodec.cpp create mode 100644 libskia/src/codec/SkIcoCodec.h create mode 100644 libskia/src/codec/SkJpegCodec.cpp create mode 100644 libskia/src/codec/SkJpegCodec.h create mode 100644 libskia/src/codec/SkJpegDecoderMgr.cpp create mode 100644 libskia/src/codec/SkJpegDecoderMgr.h create mode 100644 libskia/src/codec/SkJpegUtility.cpp create mode 100644 libskia/src/codec/SkJpegUtility.h create mode 100644 libskia/src/codec/SkMaskSwizzler.cpp create mode 100644 libskia/src/codec/SkMaskSwizzler.h create mode 100644 libskia/src/codec/SkMasks.cpp create mode 100644 libskia/src/codec/SkMasks.h create mode 100644 libskia/src/codec/SkPngCodec.cpp create mode 100644 libskia/src/codec/SkPngCodec.h create mode 100644 libskia/src/codec/SkRawAdapterCodec.cpp create mode 100644 libskia/src/codec/SkRawAdapterCodec.h create mode 100644 libskia/src/codec/SkRawCodec.cpp create mode 100644 libskia/src/codec/SkRawCodec.h create mode 100644 libskia/src/codec/SkSampledCodec.cpp create mode 100644 libskia/src/codec/SkSampledCodec.h create mode 100644 libskia/src/codec/SkSampler.cpp create mode 100644 libskia/src/codec/SkSampler.h create mode 100644 libskia/src/codec/SkStreamBuffer.cpp create mode 100644 libskia/src/codec/SkStreamBuffer.h create mode 100644 libskia/src/codec/SkSwizzler.cpp create mode 100644 libskia/src/codec/SkSwizzler.h create mode 100644 libskia/src/codec/SkWbmpCodec.cpp create mode 100644 libskia/src/codec/SkWbmpCodec.h create mode 100644 libskia/src/codec/SkWebpAdapterCodec.cpp create mode 100644 libskia/src/codec/SkWebpAdapterCodec.h create mode 100644 libskia/src/codec/SkWebpCodec.cpp create mode 100644 libskia/src/codec/SkWebpCodec.h delete mode 100644 libskia/src/core/ARGB32_Clamp_Bilinear_BitmapShader.h create mode 100644 libskia/src/core/Sk4px.h create mode 100644 libskia/src/core/Sk4x4f.h delete mode 100644 libskia/src/core/Sk64.cpp create mode 100644 libskia/src/core/SkATrace.cpp create mode 100644 libskia/src/core/SkATrace.h delete mode 100644 libskia/src/core/SkAdvancedTypefaceMetrics.cpp create mode 100644 libskia/src/core/SkAdvancedTypefaceMetrics.h create mode 100644 libskia/src/core/SkAnalyticEdge.cpp create mode 100644 libskia/src/core/SkAnalyticEdge.h create mode 100644 libskia/src/core/SkAnnotationKeys.h create mode 100644 libskia/src/core/SkAutoPixmapStorage.cpp create mode 100644 libskia/src/core/SkAutoPixmapStorage.h create mode 100644 libskia/src/core/SkBBHFactory.cpp delete mode 100644 libskia/src/core/SkBBoxHierarchyRecord.cpp delete mode 100644 libskia/src/core/SkBBoxHierarchyRecord.h delete mode 100644 libskia/src/core/SkBBoxRecord.cpp delete mode 100644 libskia/src/core/SkBBoxRecord.h create mode 100644 libskia/src/core/SkBigPicture.cpp create mode 100644 libskia/src/core/SkBigPicture.h create mode 100644 libskia/src/core/SkBitmapCache.cpp create mode 100644 libskia/src/core/SkBitmapCache.h create mode 100644 libskia/src/core/SkBitmapController.cpp create mode 100644 libskia/src/core/SkBitmapController.h delete mode 100644 libskia/src/core/SkBitmapFilter.cpp delete mode 100644 libskia/src/core/SkBitmapHeap.cpp delete mode 100644 libskia/src/core/SkBitmapHeap.h create mode 100644 libskia/src/core/SkBitmapProcState_matrix_template.h create mode 100644 libskia/src/core/SkBitmapProvider.cpp create mode 100644 libskia/src/core/SkBitmapProvider.h delete mode 100644 libskia/src/core/SkBitmapShader16BilerpTemplate.h delete mode 100644 libskia/src/core/SkBitmapShaderTemplate.h delete mode 100644 libskia/src/core/SkBitmap_scroll.cpp create mode 100644 libskia/src/core/SkBlendModePriv.h create mode 100644 libskia/src/core/SkBlitter_PM4f.cpp create mode 100644 libskia/src/core/SkBlurImageFilter.cpp create mode 100644 libskia/src/core/SkCachedData.cpp create mode 100644 libskia/src/core/SkCachedData.h create mode 100644 libskia/src/core/SkCanvasPriv.h create mode 100644 libskia/src/core/SkColorFilterShader.cpp create mode 100644 libskia/src/core/SkColorFilterShader.h create mode 100644 libskia/src/core/SkColorLookUpTable.cpp create mode 100644 libskia/src/core/SkColorLookUpTable.h create mode 100644 libskia/src/core/SkColorMatrixFilterRowMajor255.cpp create mode 100644 libskia/src/core/SkColorMatrixFilterRowMajor255.h create mode 100644 libskia/src/core/SkColorShader.cpp create mode 100644 libskia/src/core/SkColorShader.h create mode 100644 libskia/src/core/SkColorSpace.cpp create mode 100644 libskia/src/core/SkColorSpacePriv.h create mode 100644 libskia/src/core/SkColorSpaceXform.cpp create mode 100644 libskia/src/core/SkColorSpaceXformPriv.h create mode 100644 libskia/src/core/SkColorSpaceXform_A2B.cpp create mode 100644 libskia/src/core/SkColorSpaceXform_A2B.h create mode 100644 libskia/src/core/SkColorSpaceXform_Base.h create mode 100644 libskia/src/core/SkColorSpace_A2B.cpp create mode 100644 libskia/src/core/SkColorSpace_A2B.h create mode 100644 libskia/src/core/SkColorSpace_Base.h create mode 100644 libskia/src/core/SkColorSpace_ICC.cpp create mode 100644 libskia/src/core/SkColorSpace_XYZ.cpp create mode 100644 libskia/src/core/SkColorSpace_XYZ.h create mode 100644 libskia/src/core/SkComposeShader.h delete mode 100644 libskia/src/core/SkCordic.cpp delete mode 100644 libskia/src/core/SkCordic.h create mode 100644 libskia/src/core/SkCpu.cpp create mode 100644 libskia/src/core/SkCpu.h create mode 100644 libskia/src/core/SkDeduper.h delete mode 100644 libskia/src/core/SkDeviceImageFilterProxy.h create mode 100644 libskia/src/core/SkDistanceFieldGen.cpp create mode 100644 libskia/src/core/SkDistanceFieldGen.h rename libskia/{include => src}/core/SkDither.h (99%) create mode 100644 libskia/src/core/SkDocument.cpp create mode 100644 libskia/src/core/SkDrawable.cpp create mode 100644 libskia/src/core/SkEmptyShader.h rename libskia/{include => src}/core/SkEndian.h (93%) delete mode 100644 libskia/src/core/SkError.cpp delete mode 100644 libskia/src/core/SkErrorInternals.h create mode 100644 libskia/src/core/SkExchange.h create mode 100644 libskia/src/core/SkFDot6Constants.h delete mode 100644 libskia/src/core/SkFP.h delete mode 100644 libskia/src/core/SkFilterShader.cpp delete mode 100644 libskia/src/core/SkFilterShader.h create mode 100644 libskia/src/core/SkFindAndPlaceGlyph.h create mode 100644 libskia/src/core/SkFixed15.h create mode 100644 libskia/src/core/SkFixedAlloc.cpp create mode 100644 libskia/src/core/SkFixedAlloc.h delete mode 100644 libskia/src/core/SkFlate.cpp delete mode 100644 libskia/src/core/SkFlattenableBuffers.cpp delete mode 100644 libskia/src/core/SkFloat.cpp delete mode 100644 libskia/src/core/SkFloat.h delete mode 100644 libskia/src/core/SkFloatBits.cpp create mode 100644 libskia/src/core/SkFont.cpp delete mode 100644 libskia/src/core/SkFontHost.cpp create mode 100644 libskia/src/core/SkFontLCDConfig.cpp create mode 100644 libskia/src/core/SkFontMgr.cpp create mode 100644 libskia/src/core/SkFontStyle.cpp create mode 100644 libskia/src/core/SkForceCPlusPlusLinking.cpp create mode 100644 libskia/src/core/SkFuzzLogging.h rename libskia/{include => src}/core/SkGeometry.h (63%) create mode 100644 libskia/src/core/SkGlobalInitialization_core.cpp create mode 100644 libskia/src/core/SkGpuBlurUtils.cpp create mode 100644 libskia/src/core/SkGpuBlurUtils.h create mode 100644 libskia/src/core/SkHalf.cpp create mode 100644 libskia/src/core/SkHalf.h create mode 100644 libskia/src/core/SkImageCacherator.cpp create mode 100644 libskia/src/core/SkImageCacherator.h create mode 100644 libskia/src/core/SkImageFilterCache.cpp create mode 100644 libskia/src/core/SkImageFilterCache.h delete mode 100644 libskia/src/core/SkImageFilterUtils.cpp create mode 100644 libskia/src/core/SkImageGenerator.cpp create mode 100644 libskia/src/core/SkImagePriv.h delete mode 100644 libskia/src/core/SkInstCnt.cpp create mode 100644 libskia/src/core/SkLatticeIter.cpp create mode 100644 libskia/src/core/SkLatticeIter.h create mode 100644 libskia/src/core/SkLightingShader.cpp create mode 100644 libskia/src/core/SkLightingShader.h create mode 100644 libskia/src/core/SkLights.cpp rename libskia/{include => src}/core/SkLineClipper.h (93%) create mode 100644 libskia/src/core/SkLinearBitmapPipeline.cpp create mode 100644 libskia/src/core/SkLinearBitmapPipeline.h create mode 100644 libskia/src/core/SkLinearBitmapPipeline_core.h create mode 100644 libskia/src/core/SkLinearBitmapPipeline_matrix.h create mode 100644 libskia/src/core/SkLinearBitmapPipeline_sample.h create mode 100644 libskia/src/core/SkLinearBitmapPipeline_tile.h create mode 100644 libskia/src/core/SkLiteDL.cpp create mode 100644 libskia/src/core/SkLiteDL.h create mode 100644 libskia/src/core/SkLiteRecorder.cpp create mode 100644 libskia/src/core/SkLiteRecorder.h create mode 100644 libskia/src/core/SkLocalMatrixImageFilter.cpp create mode 100644 libskia/src/core/SkLocalMatrixImageFilter.h create mode 100644 libskia/src/core/SkLocalMatrixShader.cpp create mode 100644 libskia/src/core/SkLocalMatrixShader.h rename libskia/src/{utils => core}/SkMD5.cpp (94%) create mode 100644 libskia/src/core/SkMD5.h create mode 100644 libskia/src/core/SkMSAN.h create mode 100644 libskia/src/core/SkMakeUnique.h create mode 100644 libskia/src/core/SkMaskCache.cpp create mode 100644 libskia/src/core/SkMaskCache.h rename libskia/src/{utils => core}/SkMatrix44.cpp (85%) create mode 100644 libskia/src/core/SkMatrixImageFilter.cpp create mode 100644 libskia/src/core/SkMatrixImageFilter.h create mode 100644 libskia/src/core/SkMatrixPriv.h create mode 100644 libskia/src/core/SkMiniRecorder.cpp create mode 100644 libskia/src/core/SkModeColorFilter.cpp create mode 100644 libskia/src/core/SkModeColorFilter.h create mode 100644 libskia/src/core/SkMultiPictureDraw.cpp create mode 100644 libskia/src/core/SkNextID.h create mode 100644 libskia/src/core/SkNormalBevelSource.cpp create mode 100644 libskia/src/core/SkNormalBevelSource.h create mode 100644 libskia/src/core/SkNormalFlatSource.cpp create mode 100644 libskia/src/core/SkNormalFlatSource.h create mode 100644 libskia/src/core/SkNormalMapSource.cpp create mode 100644 libskia/src/core/SkNormalMapSource.h create mode 100644 libskia/src/core/SkNormalSource.cpp create mode 100644 libskia/src/core/SkNormalSource.h create mode 100644 libskia/src/core/SkNormalSourcePriv.h create mode 100644 libskia/src/core/SkNx.h delete mode 100644 libskia/src/core/SkOnce.h create mode 100644 libskia/src/core/SkOpts.cpp create mode 100644 libskia/src/core/SkOpts.h delete mode 100644 libskia/src/core/SkOrderedReadBuffer.cpp delete mode 100644 libskia/src/core/SkOrderedWriteBuffer.cpp delete mode 100644 libskia/src/core/SkOrderedWriteBuffer.h create mode 100644 libskia/src/core/SkOverdrawCanvas.cpp create mode 100644 libskia/src/core/SkOverdrawCanvas.h create mode 100644 libskia/src/core/SkPM4f.h create mode 100644 libskia/src/core/SkPM4fPriv.h delete mode 100644 libskia/src/core/SkPackBits.cpp delete mode 100644 libskia/src/core/SkPaintOptionsAndroid.cpp delete mode 100644 libskia/src/core/SkPathHeap.cpp delete mode 100644 libskia/src/core/SkPathHeap.h create mode 100644 libskia/src/core/SkPathMeasurePriv.h create mode 100644 libskia/src/core/SkPathPriv.h create mode 100644 libskia/src/core/SkPictureAnalyzer.cpp create mode 100644 libskia/src/core/SkPictureCommon.h create mode 100644 libskia/src/core/SkPictureContentInfo.cpp create mode 100644 libskia/src/core/SkPictureContentInfo.h create mode 100644 libskia/src/core/SkPictureData.cpp create mode 100644 libskia/src/core/SkPictureData.h create mode 100644 libskia/src/core/SkPictureImageGenerator.cpp create mode 100644 libskia/src/core/SkPictureRecorder.cpp create mode 100644 libskia/src/core/SkPictureShader.cpp create mode 100644 libskia/src/core/SkPictureShader.h delete mode 100644 libskia/src/core/SkPictureStateTree.cpp delete mode 100644 libskia/src/core/SkPictureStateTree.h create mode 100644 libskia/src/core/SkPipe.h create mode 100644 libskia/src/core/SkPixmap.cpp create mode 100644 libskia/src/core/SkPoint3.cpp delete mode 100644 libskia/src/core/SkProcSpriteBlitter.cpp create mode 100644 libskia/src/core/SkRWBuffer.cpp create mode 100644 libskia/src/core/SkRadialShadowMapShader.cpp create mode 100644 libskia/src/core/SkRadialShadowMapShader.h create mode 100644 libskia/src/core/SkRasterPipeline.cpp create mode 100644 libskia/src/core/SkRasterPipeline.h create mode 100644 libskia/src/core/SkRasterPipelineBlitter.cpp create mode 100644 libskia/src/core/SkReadBuffer.cpp create mode 100644 libskia/src/core/SkReadBuffer.h rename libskia/{include => src}/core/SkReader32.h (79%) create mode 100644 libskia/src/core/SkRecord.cpp create mode 100644 libskia/src/core/SkRecord.h create mode 100644 libskia/src/core/SkRecordDraw.cpp create mode 100644 libskia/src/core/SkRecordDraw.h create mode 100644 libskia/src/core/SkRecordOpts.cpp create mode 100644 libskia/src/core/SkRecordOpts.h create mode 100644 libskia/src/core/SkRecordPattern.h create mode 100644 libskia/src/core/SkRecordedDrawable.cpp create mode 100644 libskia/src/core/SkRecordedDrawable.h create mode 100644 libskia/src/core/SkRecorder.cpp create mode 100644 libskia/src/core/SkRecorder.h create mode 100644 libskia/src/core/SkRecords.cpp delete mode 100644 libskia/src/core/SkRegion_rects.cpp create mode 100644 libskia/src/core/SkResourceCache.cpp create mode 100644 libskia/src/core/SkResourceCache.h create mode 100644 libskia/src/core/SkSRGB.cpp create mode 100644 libskia/src/core/SkSRGB.h create mode 100644 libskia/src/core/SkScaleToSides.h delete mode 100644 libskia/src/core/SkScaledImageCache.cpp delete mode 100644 libskia/src/core/SkScaledImageCache.h create mode 100644 libskia/src/core/SkScan_AAAPath.cpp create mode 100644 libskia/src/core/SkSemaphore.cpp create mode 100644 libskia/src/core/SkShadowShader.cpp create mode 100644 libskia/src/core/SkShadowShader.h create mode 100644 libskia/src/core/SkSharedMutex.cpp create mode 100644 libskia/src/core/SkSharedMutex.h delete mode 100644 libskia/src/core/SkSinTable.h create mode 100644 libskia/src/core/SkSinglyLinkedList.h create mode 100644 libskia/src/core/SkSmallAllocator.h create mode 100644 libskia/src/core/SkSpanProcs.cpp create mode 100644 libskia/src/core/SkSpanProcs.h create mode 100644 libskia/src/core/SkSpecialImage.cpp create mode 100644 libskia/src/core/SkSpecialImage.h create mode 100644 libskia/src/core/SkSpecialSurface.cpp create mode 100644 libskia/src/core/SkSpecialSurface.h create mode 100644 libskia/src/core/SkSpinlock.cpp create mode 100644 libskia/src/core/SkSpriteBlitter4f.cpp create mode 100644 libskia/src/core/SkStreamPriv.h rename libskia/{include => src}/core/SkStringUtils.h (52%) create mode 100644 libskia/src/core/SkSurfacePriv.h create mode 100644 libskia/src/core/SkSwizzle.cpp create mode 100644 libskia/src/core/SkTDPQueue.h rename libskia/{include => src}/core/SkTInternalLList.h (94%) mode change 100755 => 100644 libskia/src/core/SkTLS.cpp create mode 100644 libskia/src/core/SkTMultiMap.h delete mode 100755 libskia/src/core/SkTRefArray.h create mode 100644 libskia/src/core/SkTTopoSort.h create mode 100644 libskia/src/core/SkTaskGroup.cpp create mode 100644 libskia/src/core/SkTaskGroup.h delete mode 100644 libskia/src/core/SkTemplatesPriv.h create mode 100644 libskia/src/core/SkTextBlob.cpp create mode 100644 libskia/src/core/SkTextBlobRunIterator.h create mode 100644 libskia/src/core/SkTextMapStateProc.h create mode 100644 libskia/src/core/SkThreadID.cpp delete mode 100644 libskia/src/core/SkTileGrid.cpp delete mode 100644 libskia/src/core/SkTileGrid.h delete mode 100644 libskia/src/core/SkTileGridPicture.cpp create mode 100644 libskia/src/core/SkTime.cpp create mode 100644 libskia/src/core/SkTraceEvent.h create mode 100644 libskia/src/core/SkTraceEventCommon.h rename libskia/{include => src}/core/SkUtils.h (72%) create mode 100644 libskia/src/core/SkVarAlloc.cpp create mode 100644 libskia/src/core/SkVarAlloc.h create mode 100644 libskia/src/core/SkVertState.cpp create mode 100644 libskia/src/core/SkVertState.h create mode 100644 libskia/src/core/SkWriteBuffer.cpp create mode 100644 libskia/src/core/SkXfermode4f.cpp create mode 100644 libskia/src/core/SkXfermodeF16.cpp create mode 100644 libskia/src/core/SkXfermodeInterpretation.cpp create mode 100644 libskia/src/core/SkXfermodeInterpretation.h create mode 100644 libskia/src/core/SkXfermodePriv.h create mode 100644 libskia/src/core/SkYUVPlanesCache.cpp create mode 100644 libskia/src/core/SkYUVPlanesCache.h create mode 100644 libskia/src/effects/GrAlphaThresholdFragmentProcessor.cpp create mode 100644 libskia/src/effects/GrAlphaThresholdFragmentProcessor.h create mode 100644 libskia/src/effects/GrCircleBlurFragmentProcessor.cpp create mode 100644 libskia/src/effects/GrCircleBlurFragmentProcessor.h create mode 100644 libskia/src/effects/SkAlphaThresholdFilter.cpp create mode 100644 libskia/src/effects/SkArcToPathEffect.cpp create mode 100644 libskia/src/effects/SkArithmeticModePriv.h create mode 100644 libskia/src/effects/SkArithmeticMode_gpu.cpp create mode 100644 libskia/src/effects/SkArithmeticMode_gpu.h delete mode 100644 libskia/src/effects/SkAvoidXfermode.cpp delete mode 100644 libskia/src/effects/SkBicubicImageFilter.cpp delete mode 100644 libskia/src/effects/SkBitmapSource.cpp delete mode 100644 libskia/src/effects/SkBlurImageFilter.cpp create mode 100644 libskia/src/effects/SkColorCubeFilter.cpp mode change 100755 => 100644 libskia/src/effects/SkColorFilterImageFilter.cpp delete mode 100644 libskia/src/effects/SkColorFilters.cpp create mode 100644 libskia/src/effects/SkGammaColorFilter.cpp create mode 100644 libskia/src/effects/SkGaussianEdgeShader.cpp delete mode 100644 libskia/src/effects/SkGpuBlurUtils.cpp delete mode 100644 libskia/src/effects/SkGpuBlurUtils.h create mode 100644 libskia/src/effects/SkImageSource.cpp delete mode 100644 libskia/src/effects/SkKernel33MaskFilter.cpp delete mode 100644 libskia/src/effects/SkLerpXfermode.cpp mode change 100755 => 100644 libskia/src/effects/SkMergeImageFilter.cpp create mode 100644 libskia/src/effects/SkOverdrawColorFilter.cpp create mode 100644 libskia/src/effects/SkOverdrawColorFilter.h create mode 100644 libskia/src/effects/SkPackBits.cpp create mode 100644 libskia/src/effects/SkPackBits.h create mode 100644 libskia/src/effects/SkPaintImageFilter.cpp delete mode 100644 libskia/src/effects/SkPixelXorXfermode.cpp delete mode 100644 libskia/src/effects/SkPorterDuff.cpp create mode 100644 libskia/src/effects/SkRRectsGaussianEdgeMaskFilter.cpp delete mode 100644 libskia/src/effects/SkRectShaderImageFilter.cpp create mode 100644 libskia/src/effects/SkShadowMaskFilter.cpp delete mode 100644 libskia/src/effects/SkStippleMaskFilter.cpp delete mode 100755 libskia/src/effects/SkTestImageFilters.cpp delete mode 100644 libskia/src/effects/SkTransparentShader.cpp create mode 100644 libskia/src/effects/gradients/Sk4fGradientBase.cpp create mode 100644 libskia/src/effects/gradients/Sk4fGradientBase.h create mode 100644 libskia/src/effects/gradients/Sk4fGradientPriv.h create mode 100644 libskia/src/effects/gradients/Sk4fLinearGradient.cpp create mode 100644 libskia/src/effects/gradients/Sk4fLinearGradient.h rename libskia/src/effects/gradients/{SkBitmapCache.cpp => SkGradientBitmapCache.cpp} (73%) rename libskia/src/effects/gradients/{SkBitmapCache.h => SkGradientBitmapCache.h} (65%) delete mode 100644 libskia/src/effects/gradients/SkRadialGradient_Table.h create mode 100644 libskia/src/effects/gradients/SkTwoPointConicalGradient_gpu.cpp create mode 100644 libskia/src/effects/gradients/SkTwoPointConicalGradient_gpu.h delete mode 100644 libskia/src/effects/gradients/SkTwoPointRadialGradient.cpp delete mode 100644 libskia/src/effects/gradients/SkTwoPointRadialGradient.h delete mode 100644 libskia/src/fonts/SkFontMgr_fontconfig.cpp create mode 100644 libskia/src/fonts/SkFontMgr_indirect.cpp create mode 100644 libskia/src/fonts/SkRandomScalerContext.cpp create mode 100644 libskia/src/fonts/SkRandomScalerContext.h create mode 100644 libskia/src/fonts/SkRemotableFontMgr.cpp create mode 100644 libskia/src/fonts/SkTestScalerContext.cpp create mode 100644 libskia/src/fonts/SkTestScalerContext.h delete mode 100644 libskia/src/gpu/FlingState.cpp delete mode 100644 libskia/src/gpu/GrAAConvexPathRenderer.cpp delete mode 100644 libskia/src/gpu/GrAAConvexPathRenderer.h delete mode 100644 libskia/src/gpu/GrAAHairLinePathRenderer.cpp delete mode 100644 libskia/src/gpu/GrAAHairLinePathRenderer.h delete mode 100644 libskia/src/gpu/GrAARectRenderer.cpp delete mode 100644 libskia/src/gpu/GrAARectRenderer.h delete mode 100644 libskia/src/gpu/GrAddPathRenderers_default.cpp delete mode 100644 libskia/src/gpu/GrAddPathRenderers_none.cpp delete mode 100644 libskia/src/gpu/GrAllocPool.cpp delete mode 100644 libskia/src/gpu/GrAllocPool.h mode change 100755 => 100644 libskia/src/gpu/GrAllocator.h create mode 100644 libskia/src/gpu/GrAppliedClip.h delete mode 100644 libskia/src/gpu/GrAtlas.cpp delete mode 100644 libskia/src/gpu/GrAtlas.h create mode 100644 libskia/src/gpu/GrAuditTrail.cpp create mode 100644 libskia/src/gpu/GrAutoLocaleSetter.h create mode 100644 libskia/src/gpu/GrBatchAtlas.cpp create mode 100644 libskia/src/gpu/GrBatchAtlas.h create mode 100644 libskia/src/gpu/GrBatchFlushState.cpp create mode 100644 libskia/src/gpu/GrBatchFlushState.h create mode 100644 libskia/src/gpu/GrBatchTest.cpp create mode 100644 libskia/src/gpu/GrBatchTest.h delete mode 100644 libskia/src/gpu/GrBinHashKey.h delete mode 100755 libskia/src/gpu/GrBitmapTextContext.cpp create mode 100644 libskia/src/gpu/GrBitmapTextureMaker.cpp create mode 100644 libskia/src/gpu/GrBitmapTextureMaker.h delete mode 100644 libskia/src/gpu/GrBlend.h create mode 100644 libskia/src/gpu/GrBlurUtils.cpp create mode 100644 libskia/src/gpu/GrBlurUtils.h create mode 100644 libskia/src/gpu/GrBuffer.cpp delete mode 100644 libskia/src/gpu/GrCacheID.cpp create mode 100644 libskia/src/gpu/GrCaps.cpp delete mode 100644 libskia/src/gpu/GrClipData.cpp delete mode 100644 libskia/src/gpu/GrClipMaskCache.cpp delete mode 100644 libskia/src/gpu/GrClipMaskCache.h delete mode 100644 libskia/src/gpu/GrClipMaskManager.cpp delete mode 100644 libskia/src/gpu/GrClipMaskManager.h create mode 100644 libskia/src/gpu/GrClipStackClip.cpp create mode 100644 libskia/src/gpu/GrClipStackClip.h create mode 100644 libskia/src/gpu/GrColorSpaceXform.cpp create mode 100644 libskia/src/gpu/GrContextPriv.h create mode 100644 libskia/src/gpu/GrCoordTransform.cpp create mode 100644 libskia/src/gpu/GrDefaultGeoProcFactory.cpp create mode 100644 libskia/src/gpu/GrDefaultGeoProcFactory.h delete mode 100644 libskia/src/gpu/GrDefaultPathRenderer.cpp delete mode 100644 libskia/src/gpu/GrDefaultPathRenderer.h delete mode 100755 libskia/src/gpu/GrDistanceFieldTextContext.cpp delete mode 100644 libskia/src/gpu/GrDrawState.cpp delete mode 100644 libskia/src/gpu/GrDrawState.h delete mode 100644 libskia/src/gpu/GrDrawTarget.cpp delete mode 100644 libskia/src/gpu/GrDrawTarget.h delete mode 100644 libskia/src/gpu/GrDrawTargetCaps.h create mode 100644 libskia/src/gpu/GrDrawingManager.cpp create mode 100644 libskia/src/gpu/GrDrawingManager.h delete mode 100644 libskia/src/gpu/GrEffect.cpp create mode 100644 libskia/src/gpu/GrFixedClip.cpp create mode 100644 libskia/src/gpu/GrFixedClip.h create mode 100644 libskia/src/gpu/GrFragmentProcessor.cpp delete mode 100644 libskia/src/gpu/GrGeometryBuffer.h create mode 100644 libskia/src/gpu/GrGeometryProcessor.h create mode 100644 libskia/src/gpu/GrGlyph.h create mode 100644 libskia/src/gpu/GrGpuCommandBuffer.cpp create mode 100644 libskia/src/gpu/GrGpuCommandBuffer.h create mode 100644 libskia/src/gpu/GrGpuFactory.h create mode 100644 libskia/src/gpu/GrGpuResource.cpp create mode 100644 libskia/src/gpu/GrGpuResourceCacheAccess.h create mode 100644 libskia/src/gpu/GrGpuResourcePriv.h create mode 100644 libskia/src/gpu/GrGpuResourceRef.cpp create mode 100644 libskia/src/gpu/GrImageTextureMaker.cpp create mode 100644 libskia/src/gpu/GrImageTextureMaker.h delete mode 100644 libskia/src/gpu/GrInOrderDrawBuffer.cpp delete mode 100644 libskia/src/gpu/GrInOrderDrawBuffer.h delete mode 100644 libskia/src/gpu/GrIndexBuffer.h create mode 100644 libskia/src/gpu/GrInvariantOutput.cpp delete mode 100644 libskia/src/gpu/GrMemory.cpp create mode 100644 libskia/src/gpu/GrMesh.h create mode 100644 libskia/src/gpu/GrNonAtomicRef.h create mode 100644 libskia/src/gpu/GrOpList.cpp create mode 100644 libskia/src/gpu/GrOpList.h create mode 100644 libskia/src/gpu/GrPLSGeometryProcessor.h create mode 100644 libskia/src/gpu/GrPathProcessor.cpp create mode 100644 libskia/src/gpu/GrPathProcessor.h create mode 100644 libskia/src/gpu/GrPathRange.cpp create mode 100644 libskia/src/gpu/GrPathRange.h rename libskia/{include => src}/gpu/GrPathRendererChain.h (69%) create mode 100644 libskia/src/gpu/GrPathRendering.cpp create mode 100644 libskia/src/gpu/GrPathRendering.h create mode 100644 libskia/src/gpu/GrPathRenderingRenderTargetContext.cpp create mode 100644 libskia/src/gpu/GrPathRenderingRenderTargetContext.h create mode 100644 libskia/src/gpu/GrPendingProgramElement.h create mode 100644 libskia/src/gpu/GrPipeline.cpp create mode 100644 libskia/src/gpu/GrPipeline.h create mode 100644 libskia/src/gpu/GrPipelineBuilder.cpp create mode 100644 libskia/src/gpu/GrPipelineBuilder.h delete mode 100644 libskia/src/gpu/GrPlotMgr.h create mode 100644 libskia/src/gpu/GrPrimitiveProcessor.cpp create mode 100644 libskia/src/gpu/GrPrimitiveProcessor.h create mode 100644 libskia/src/gpu/GrProcOptInfo.cpp create mode 100644 libskia/src/gpu/GrProcOptInfo.h create mode 100644 libskia/src/gpu/GrProcessor.cpp create mode 100644 libskia/src/gpu/GrProcessorUnitTest.cpp create mode 100644 libskia/src/gpu/GrProgramDesc.cpp create mode 100644 libskia/src/gpu/GrProgramDesc.h create mode 100644 libskia/src/gpu/GrProgramElement.cpp create mode 100644 libskia/src/gpu/GrQuad.h rename libskia/{include => src}/gpu/GrRect.h (51%) delete mode 100644 libskia/src/gpu/GrRectanizer.cpp delete mode 100644 libskia/src/gpu/GrRectanizer_fifo.cpp create mode 100644 libskia/src/gpu/GrRectanizer_pow2.cpp create mode 100644 libskia/src/gpu/GrRectanizer_pow2.h mode change 100755 => 100644 libskia/src/gpu/GrRectanizer_skyline.cpp create mode 100644 libskia/src/gpu/GrRectanizer_skyline.h delete mode 100644 libskia/src/gpu/GrRedBlackTree.h create mode 100644 libskia/src/gpu/GrRenderTargetContext.cpp create mode 100644 libskia/src/gpu/GrRenderTargetContextPriv.h create mode 100644 libskia/src/gpu/GrRenderTargetOpList.cpp create mode 100644 libskia/src/gpu/GrRenderTargetOpList.h create mode 100644 libskia/src/gpu/GrRenderTargetPriv.h create mode 100644 libskia/src/gpu/GrRenderTargetProxy.cpp delete mode 100644 libskia/src/gpu/GrResource.cpp create mode 100644 libskia/src/gpu/GrResourceHandle.h create mode 100644 libskia/src/gpu/GrResourceProvider.cpp create mode 100644 libskia/src/gpu/GrResourceProvider.h create mode 100644 libskia/src/gpu/GrScissorState.h create mode 100644 libskia/src/gpu/GrShaderCaps.cpp create mode 100644 libskia/src/gpu/GrShaderVar.cpp create mode 100644 libskia/src/gpu/GrShape.cpp create mode 100644 libskia/src/gpu/GrShape.h delete mode 100644 libskia/src/gpu/GrStencil.cpp delete mode 100644 libskia/src/gpu/GrStencil.h delete mode 100644 libskia/src/gpu/GrStencilAndCoverPathRenderer.cpp delete mode 100644 libskia/src/gpu/GrStencilAndCoverPathRenderer.h create mode 100644 libskia/src/gpu/GrStencilAttachment.cpp create mode 100644 libskia/src/gpu/GrStencilAttachment.h delete mode 100644 libskia/src/gpu/GrStencilBuffer.cpp delete mode 100644 libskia/src/gpu/GrStencilBuffer.h create mode 100644 libskia/src/gpu/GrStencilSettings.cpp create mode 100644 libskia/src/gpu/GrStencilSettings.h create mode 100644 libskia/src/gpu/GrStyle.cpp create mode 100644 libskia/src/gpu/GrStyle.h create mode 100644 libskia/src/gpu/GrSurfaceContext.cpp create mode 100644 libskia/src/gpu/GrSurfacePriv.h create mode 100644 libskia/src/gpu/GrSurfaceProxy.cpp delete mode 100644 libskia/src/gpu/GrTBSearch.h delete mode 100644 libskia/src/gpu/GrTHashTable.h create mode 100644 libskia/src/gpu/GrTRecorder.h delete mode 100644 libskia/src/gpu/GrTemplates.h create mode 100644 libskia/src/gpu/GrTessellator.cpp create mode 100644 libskia/src/gpu/GrTessellator.h delete mode 100644 libskia/src/gpu/GrTest.cpp delete mode 100644 libskia/src/gpu/GrTest.h create mode 100644 libskia/src/gpu/GrTestUtils.cpp delete mode 100644 libskia/src/gpu/GrTextContext.cpp delete mode 100644 libskia/src/gpu/GrTextStrike.cpp delete mode 100644 libskia/src/gpu/GrTextStrike.h delete mode 100644 libskia/src/gpu/GrTextStrike_impl.h delete mode 100644 libskia/src/gpu/GrTextureAccess.cpp create mode 100644 libskia/src/gpu/GrTextureAdjuster.cpp create mode 100644 libskia/src/gpu/GrTextureAdjuster.h create mode 100644 libskia/src/gpu/GrTextureContext.cpp create mode 100644 libskia/src/gpu/GrTextureMaker.cpp create mode 100644 libskia/src/gpu/GrTextureMaker.h create mode 100644 libskia/src/gpu/GrTextureOpList.cpp create mode 100644 libskia/src/gpu/GrTextureOpList.h create mode 100644 libskia/src/gpu/GrTexturePriv.h create mode 100644 libskia/src/gpu/GrTextureProducer.cpp create mode 100644 libskia/src/gpu/GrTextureProducer.h create mode 100644 libskia/src/gpu/GrTextureProvider.cpp create mode 100644 libskia/src/gpu/GrTextureProxy.cpp create mode 100644 libskia/src/gpu/GrTextureRenderTargetProxy.cpp create mode 100644 libskia/src/gpu/GrTextureToYUVPlanes.cpp create mode 100644 libskia/src/gpu/GrTextureToYUVPlanes.h create mode 100644 libskia/src/gpu/GrTraceMarker.cpp create mode 100644 libskia/src/gpu/GrTraceMarker.h create mode 100644 libskia/src/gpu/GrTracing.h create mode 100644 libskia/src/gpu/GrUserStencilSettings.h delete mode 100644 libskia/src/gpu/GrVertexBuffer.h create mode 100644 libskia/src/gpu/GrWindowRectangles.h create mode 100644 libskia/src/gpu/GrWindowRectsState.h create mode 100644 libskia/src/gpu/GrXferProcessor.cpp create mode 100644 libskia/src/gpu/GrYUVProvider.cpp create mode 100644 libskia/src/gpu/GrYUVProvider.h create mode 100644 libskia/src/gpu/SkGpuDevice.h create mode 100644 libskia/src/gpu/SkGpuDevice_drawTexture.cpp delete mode 100644 libskia/src/gpu/SkGrFontScaler.cpp delete mode 100644 libskia/src/gpu/SkGrPixelRef.cpp create mode 100644 libskia/src/gpu/SkGrPriv.h create mode 100644 libskia/src/gpu/batches/GrAAConvexPathRenderer.cpp create mode 100644 libskia/src/gpu/batches/GrAAConvexPathRenderer.h create mode 100644 libskia/src/gpu/batches/GrAAConvexTessellator.cpp create mode 100644 libskia/src/gpu/batches/GrAAConvexTessellator.h create mode 100644 libskia/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp create mode 100644 libskia/src/gpu/batches/GrAADistanceFieldPathRenderer.h create mode 100644 libskia/src/gpu/batches/GrAAFillRectBatch.cpp create mode 100644 libskia/src/gpu/batches/GrAAFillRectBatch.h create mode 100644 libskia/src/gpu/batches/GrAAHairLinePathRenderer.cpp create mode 100644 libskia/src/gpu/batches/GrAAHairLinePathRenderer.h create mode 100644 libskia/src/gpu/batches/GrAALinearizingConvexPathRenderer.cpp create mode 100644 libskia/src/gpu/batches/GrAALinearizingConvexPathRenderer.h create mode 100644 libskia/src/gpu/batches/GrAAStrokeRectBatch.cpp create mode 100644 libskia/src/gpu/batches/GrAAStrokeRectBatch.h create mode 100644 libskia/src/gpu/batches/GrAnalyticRectBatch.cpp create mode 100644 libskia/src/gpu/batches/GrAnalyticRectBatch.h create mode 100644 libskia/src/gpu/batches/GrAtlasTextBatch.cpp create mode 100644 libskia/src/gpu/batches/GrAtlasTextBatch.h create mode 100644 libskia/src/gpu/batches/GrClearBatch.h create mode 100644 libskia/src/gpu/batches/GrClearStencilClipBatch.h create mode 100644 libskia/src/gpu/batches/GrCopySurfaceBatch.cpp create mode 100644 libskia/src/gpu/batches/GrCopySurfaceBatch.h create mode 100644 libskia/src/gpu/batches/GrDashLinePathRenderer.cpp create mode 100644 libskia/src/gpu/batches/GrDashLinePathRenderer.h create mode 100644 libskia/src/gpu/batches/GrDefaultPathRenderer.cpp create mode 100644 libskia/src/gpu/batches/GrDefaultPathRenderer.h create mode 100644 libskia/src/gpu/batches/GrDiscardBatch.h create mode 100644 libskia/src/gpu/batches/GrDrawAtlasBatch.cpp create mode 100644 libskia/src/gpu/batches/GrDrawAtlasBatch.h create mode 100644 libskia/src/gpu/batches/GrDrawOp.cpp create mode 100644 libskia/src/gpu/batches/GrDrawOp.h create mode 100644 libskia/src/gpu/batches/GrDrawPathBatch.cpp create mode 100644 libskia/src/gpu/batches/GrDrawPathBatch.h create mode 100644 libskia/src/gpu/batches/GrDrawVerticesBatch.cpp create mode 100644 libskia/src/gpu/batches/GrDrawVerticesBatch.h create mode 100644 libskia/src/gpu/batches/GrMSAAPathRenderer.cpp create mode 100644 libskia/src/gpu/batches/GrMSAAPathRenderer.h create mode 100644 libskia/src/gpu/batches/GrMeshDrawOp.cpp create mode 100644 libskia/src/gpu/batches/GrMeshDrawOp.h create mode 100644 libskia/src/gpu/batches/GrNinePatch.cpp create mode 100644 libskia/src/gpu/batches/GrNinePatch.h create mode 100644 libskia/src/gpu/batches/GrNonAAFillRectBatch.cpp create mode 100644 libskia/src/gpu/batches/GrNonAAFillRectBatch.h create mode 100644 libskia/src/gpu/batches/GrNonAAFillRectPerspectiveBatch.cpp create mode 100644 libskia/src/gpu/batches/GrNonAAStrokeRectBatch.cpp create mode 100644 libskia/src/gpu/batches/GrNonAAStrokeRectBatch.h create mode 100644 libskia/src/gpu/batches/GrOp.cpp create mode 100644 libskia/src/gpu/batches/GrOp.h create mode 100644 libskia/src/gpu/batches/GrPLSPathRenderer.cpp create mode 100644 libskia/src/gpu/batches/GrPLSPathRenderer.h create mode 100644 libskia/src/gpu/batches/GrPathStencilSettings.h create mode 100644 libskia/src/gpu/batches/GrRectBatchFactory.cpp create mode 100644 libskia/src/gpu/batches/GrRectBatchFactory.h create mode 100644 libskia/src/gpu/batches/GrRegionBatch.cpp create mode 100644 libskia/src/gpu/batches/GrRegionBatch.h create mode 100644 libskia/src/gpu/batches/GrShadowRRectBatch.cpp create mode 100644 libskia/src/gpu/batches/GrShadowRRectBatch.h create mode 100644 libskia/src/gpu/batches/GrStencilAndCoverPathRenderer.cpp create mode 100644 libskia/src/gpu/batches/GrStencilAndCoverPathRenderer.h create mode 100644 libskia/src/gpu/batches/GrStencilPathBatch.h create mode 100644 libskia/src/gpu/batches/GrTessellatingPathRenderer.cpp create mode 100644 libskia/src/gpu/batches/GrTessellatingPathRenderer.h create mode 100644 libskia/src/gpu/batches/GrTestBatch.h create mode 100644 libskia/src/gpu/effects/GrBitmapTextGeoProc.cpp create mode 100644 libskia/src/gpu/effects/GrBitmapTextGeoProc.h create mode 100644 libskia/src/gpu/effects/GrConstColorProcessor.cpp create mode 100644 libskia/src/gpu/effects/GrConvexPolyEffect.cpp create mode 100644 libskia/src/gpu/effects/GrConvexPolyEffect.h create mode 100644 libskia/src/gpu/effects/GrCoverageSetOpXP.cpp delete mode 100644 libskia/src/gpu/effects/GrCustomCoordsTextureEffect.cpp delete mode 100644 libskia/src/gpu/effects/GrCustomCoordsTextureEffect.h create mode 100644 libskia/src/gpu/effects/GrCustomXfermode.cpp create mode 100644 libskia/src/gpu/effects/GrDashingEffect.cpp create mode 100644 libskia/src/gpu/effects/GrDashingEffect.h create mode 100644 libskia/src/gpu/effects/GrDisableColorXP.cpp create mode 100644 libskia/src/gpu/effects/GrDisableColorXP.h create mode 100644 libskia/src/gpu/effects/GrDistanceFieldGeoProc.cpp create mode 100644 libskia/src/gpu/effects/GrDistanceFieldGeoProc.h delete mode 100755 libskia/src/gpu/effects/GrDistanceFieldTextureEffect.cpp delete mode 100755 libskia/src/gpu/effects/GrDistanceFieldTextureEffect.h create mode 100644 libskia/src/gpu/effects/GrDitherEffect.cpp create mode 100644 libskia/src/gpu/effects/GrDitherEffect.h create mode 100644 libskia/src/gpu/effects/GrGammaEffect.cpp create mode 100644 libskia/src/gpu/effects/GrGammaEffect.h create mode 100644 libskia/src/gpu/effects/GrMatrixConvolutionEffect.cpp create mode 100644 libskia/src/gpu/effects/GrMatrixConvolutionEffect.h create mode 100644 libskia/src/gpu/effects/GrOvalEffect.cpp create mode 100644 libskia/src/gpu/effects/GrOvalEffect.h create mode 100644 libskia/src/gpu/effects/GrPorterDuffXferProcessor.cpp create mode 100644 libskia/src/gpu/effects/GrRRectEffect.cpp create mode 100644 libskia/src/gpu/effects/GrRRectEffect.h create mode 100644 libskia/src/gpu/effects/GrShadowGeoProc.cpp create mode 100644 libskia/src/gpu/effects/GrShadowGeoProc.h delete mode 100644 libskia/src/gpu/effects/GrVertexEffect.h create mode 100644 libskia/src/gpu/effects/GrXfermodeFragmentProcessor.cpp create mode 100644 libskia/src/gpu/effects/GrYUVEffect.cpp create mode 100644 libskia/src/gpu/effects/GrYUVEffect.h create mode 100644 libskia/src/gpu/gl/GrGLAssembleInterface.cpp create mode 100644 libskia/src/gpu/gl/GrGLBuffer.cpp create mode 100644 libskia/src/gpu/gl/GrGLBuffer.h delete mode 100644 libskia/src/gpu/gl/GrGLBufferImpl.cpp delete mode 100644 libskia/src/gpu/gl/GrGLBufferImpl.h delete mode 100644 libskia/src/gpu/gl/GrGLEffect.h create mode 100644 libskia/src/gpu/gl/GrGLGLSL.cpp create mode 100644 libskia/src/gpu/gl/GrGLGLSL.h create mode 100644 libskia/src/gpu/gl/GrGLGpu.cpp create mode 100644 libskia/src/gpu/gl/GrGLGpu.h create mode 100644 libskia/src/gpu/gl/GrGLGpuCommandBuffer.h create mode 100644 libskia/src/gpu/gl/GrGLGpuProgramCache.cpp delete mode 100644 libskia/src/gpu/gl/GrGLIndexBuffer.cpp delete mode 100644 libskia/src/gpu/gl/GrGLIndexBuffer.h delete mode 100644 libskia/src/gpu/gl/GrGLNoOpInterface.cpp delete mode 100644 libskia/src/gpu/gl/GrGLNoOpInterface.h create mode 100644 libskia/src/gpu/gl/GrGLPathRange.cpp create mode 100644 libskia/src/gpu/gl/GrGLPathRange.h create mode 100644 libskia/src/gpu/gl/GrGLPathRendering.cpp create mode 100644 libskia/src/gpu/gl/GrGLPathRendering.h create mode 100644 libskia/src/gpu/gl/GrGLProgramDataManager.cpp create mode 100644 libskia/src/gpu/gl/GrGLProgramDataManager.h delete mode 100644 libskia/src/gpu/gl/GrGLProgramDesc.cpp delete mode 100644 libskia/src/gpu/gl/GrGLProgramDesc.h delete mode 100644 libskia/src/gpu/gl/GrGLProgramEffects.cpp delete mode 100644 libskia/src/gpu/gl/GrGLProgramEffects.h delete mode 100644 libskia/src/gpu/gl/GrGLSL.cpp delete mode 100644 libskia/src/gpu/gl/GrGLShaderBuilder.cpp delete mode 100644 libskia/src/gpu/gl/GrGLShaderBuilder.h delete mode 100644 libskia/src/gpu/gl/GrGLShaderVar.h create mode 100644 libskia/src/gpu/gl/GrGLStencilAttachment.cpp create mode 100644 libskia/src/gpu/gl/GrGLStencilAttachment.h delete mode 100644 libskia/src/gpu/gl/GrGLStencilBuffer.cpp delete mode 100644 libskia/src/gpu/gl/GrGLStencilBuffer.h create mode 100644 libskia/src/gpu/gl/GrGLTestInterface.cpp create mode 100644 libskia/src/gpu/gl/GrGLTestInterface.h create mode 100644 libskia/src/gpu/gl/GrGLTextureRenderTarget.cpp create mode 100644 libskia/src/gpu/gl/GrGLTextureRenderTarget.h delete mode 100644 libskia/src/gpu/gl/GrGLUniformHandle.h create mode 100644 libskia/src/gpu/gl/GrGLUniformHandler.cpp create mode 100644 libskia/src/gpu/gl/GrGLUniformHandler.h delete mode 100644 libskia/src/gpu/gl/GrGLUniformManager.cpp delete mode 100644 libskia/src/gpu/gl/GrGLUniformManager.h create mode 100644 libskia/src/gpu/gl/GrGLVaryingHandler.cpp create mode 100644 libskia/src/gpu/gl/GrGLVaryingHandler.h delete mode 100644 libskia/src/gpu/gl/GrGLVertexBuffer.cpp delete mode 100644 libskia/src/gpu/gl/GrGLVertexBuffer.h delete mode 100644 libskia/src/gpu/gl/GrGLVertexEffect.h delete mode 100644 libskia/src/gpu/gl/GrGpuGL.cpp delete mode 100644 libskia/src/gpu/gl/GrGpuGL.h delete mode 100644 libskia/src/gpu/gl/GrGpuGL_program.cpp delete mode 100644 libskia/src/gpu/gl/SkGLContextHelper.cpp delete mode 100644 libskia/src/gpu/gl/android/SkNativeGLContext_android.cpp delete mode 100644 libskia/src/gpu/gl/angle/GrGLCreateANGLEInterface.cpp delete mode 100644 libskia/src/gpu/gl/angle/SkANGLEGLContext.cpp create mode 100644 libskia/src/gpu/gl/builders/GrGLProgramBuilder.cpp create mode 100644 libskia/src/gpu/gl/builders/GrGLProgramBuilder.h create mode 100644 libskia/src/gpu/gl/builders/GrGLSLPrettyPrint.cpp create mode 100644 libskia/src/gpu/gl/builders/GrGLShaderStringBuilder.cpp create mode 100644 libskia/src/gpu/gl/builders/GrGLShaderStringBuilder.h delete mode 100644 libskia/src/gpu/gl/debug/GrBufferObj.cpp delete mode 100644 libskia/src/gpu/gl/debug/GrBufferObj.h delete mode 100644 libskia/src/gpu/gl/debug/GrDebugGL.cpp delete mode 100644 libskia/src/gpu/gl/debug/GrDebugGL.h delete mode 100644 libskia/src/gpu/gl/debug/GrFBBindableObj.h delete mode 100644 libskia/src/gpu/gl/debug/GrFakeRefObj.h delete mode 100644 libskia/src/gpu/gl/debug/GrFrameBufferObj.cpp delete mode 100644 libskia/src/gpu/gl/debug/GrFrameBufferObj.h delete mode 100644 libskia/src/gpu/gl/debug/GrGLCreateDebugInterface.cpp delete mode 100644 libskia/src/gpu/gl/debug/GrProgramObj.cpp delete mode 100644 libskia/src/gpu/gl/debug/GrProgramObj.h delete mode 100644 libskia/src/gpu/gl/debug/GrRenderBufferObj.h delete mode 100644 libskia/src/gpu/gl/debug/GrShaderObj.cpp delete mode 100644 libskia/src/gpu/gl/debug/GrShaderObj.h delete mode 100644 libskia/src/gpu/gl/debug/GrTextureObj.cpp delete mode 100644 libskia/src/gpu/gl/debug/GrTextureObj.h delete mode 100644 libskia/src/gpu/gl/debug/GrTextureUnitObj.cpp delete mode 100644 libskia/src/gpu/gl/debug/GrTextureUnitObj.h delete mode 100644 libskia/src/gpu/gl/debug/GrVertexArrayObj.h delete mode 100644 libskia/src/gpu/gl/debug/SkDebugGLContext.cpp create mode 100644 libskia/src/gpu/gl/egl/GrGLCreateNativeInterface_egl.cpp create mode 100644 libskia/src/gpu/gl/glfw/GrGLCreateNativeInterface_glfw.cpp create mode 100644 libskia/src/gpu/gl/glx/GrGLCreateNativeInterface_glx.cpp delete mode 100644 libskia/src/gpu/gl/iOS/SkNativeGLContext_iOS.mm delete mode 100644 libskia/src/gpu/gl/mac/SkNativeGLContext_mac.cpp delete mode 100644 libskia/src/gpu/gl/mesa/GrGLCreateMesaInterface.cpp delete mode 100644 libskia/src/gpu/gl/mesa/SkMesaGLContext.cpp delete mode 100644 libskia/src/gpu/gl/nacl/SkNativeGLContext_nacl.cpp delete mode 100644 libskia/src/gpu/gl/unix/GrGLCreateNativeInterface_unix.cpp delete mode 100644 libskia/src/gpu/gl/unix/SkNativeGLContext_unix.cpp delete mode 100644 libskia/src/gpu/gl/win/SkNativeGLContext_win.cpp create mode 100644 libskia/src/gpu/glsl/GrGLSL.cpp create mode 100644 libskia/src/gpu/glsl/GrGLSLBlend.cpp create mode 100644 libskia/src/gpu/glsl/GrGLSLBlend.h create mode 100644 libskia/src/gpu/glsl/GrGLSLColorSpaceXformHelper.h create mode 100644 libskia/src/gpu/glsl/GrGLSLFragmentProcessor.cpp create mode 100644 libskia/src/gpu/glsl/GrGLSLFragmentProcessor.h create mode 100644 libskia/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp create mode 100644 libskia/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h create mode 100644 libskia/src/gpu/glsl/GrGLSLGeometryProcessor.cpp create mode 100644 libskia/src/gpu/glsl/GrGLSLGeometryProcessor.h create mode 100644 libskia/src/gpu/glsl/GrGLSLGeometryShaderBuilder.cpp create mode 100644 libskia/src/gpu/glsl/GrGLSLGeometryShaderBuilder.h create mode 100644 libskia/src/gpu/glsl/GrGLSLPLSPathRendering.h create mode 100644 libskia/src/gpu/glsl/GrGLSLPrimitiveProcessor.cpp create mode 100644 libskia/src/gpu/glsl/GrGLSLPrimitiveProcessor.h create mode 100644 libskia/src/gpu/glsl/GrGLSLProgramBuilder.cpp create mode 100644 libskia/src/gpu/glsl/GrGLSLProgramBuilder.h create mode 100644 libskia/src/gpu/glsl/GrGLSLProgramDataManager.cpp create mode 100644 libskia/src/gpu/glsl/GrGLSLProgramDataManager.h create mode 100644 libskia/src/gpu/glsl/GrGLSLShaderBuilder.cpp create mode 100644 libskia/src/gpu/glsl/GrGLSLShaderBuilder.h create mode 100644 libskia/src/gpu/glsl/GrGLSLUniformHandler.h create mode 100644 libskia/src/gpu/glsl/GrGLSLUtil.cpp create mode 100644 libskia/src/gpu/glsl/GrGLSLUtil.h create mode 100644 libskia/src/gpu/glsl/GrGLSLVarying.cpp create mode 100644 libskia/src/gpu/glsl/GrGLSLVarying.h create mode 100644 libskia/src/gpu/glsl/GrGLSLVertexShaderBuilder.cpp create mode 100644 libskia/src/gpu/glsl/GrGLSLVertexShaderBuilder.h create mode 100644 libskia/src/gpu/glsl/GrGLSLXferProcessor.cpp create mode 100644 libskia/src/gpu/glsl/GrGLSLXferProcessor.h create mode 100644 libskia/src/gpu/instanced/GLInstancedRendering.cpp create mode 100644 libskia/src/gpu/instanced/GLInstancedRendering.h create mode 100644 libskia/src/gpu/instanced/InstanceProcessor.cpp create mode 100644 libskia/src/gpu/instanced/InstanceProcessor.h create mode 100644 libskia/src/gpu/instanced/InstancedRendering.cpp create mode 100644 libskia/src/gpu/instanced/InstancedRendering.h create mode 100644 libskia/src/gpu/instanced/InstancedRenderingTypes.h create mode 100644 libskia/src/gpu/text/GrAtlasTextBlob.cpp create mode 100644 libskia/src/gpu/text/GrAtlasTextBlob.h create mode 100644 libskia/src/gpu/text/GrAtlasTextBlob_regenInBatch.cpp create mode 100644 libskia/src/gpu/text/GrAtlasTextContext.cpp create mode 100644 libskia/src/gpu/text/GrAtlasTextContext.h create mode 100644 libskia/src/gpu/text/GrBatchFontCache.cpp create mode 100644 libskia/src/gpu/text/GrBatchFontCache.h create mode 100644 libskia/src/gpu/text/GrDistanceFieldAdjustTable.cpp create mode 100644 libskia/src/gpu/text/GrDistanceFieldAdjustTable.h create mode 100644 libskia/src/gpu/text/GrStencilAndCoverTextContext.cpp create mode 100644 libskia/src/gpu/text/GrStencilAndCoverTextContext.h create mode 100644 libskia/src/gpu/text/GrTextBlobCache.cpp create mode 100644 libskia/src/gpu/text/GrTextBlobCache.h create mode 100644 libskia/src/gpu/text/GrTextUtils.cpp create mode 100644 libskia/src/gpu/text/GrTextUtils.h create mode 100644 libskia/src/gpu/vk/GrVkBackendContext.cpp create mode 100644 libskia/src/gpu/vk/GrVkBuffer.cpp create mode 100644 libskia/src/gpu/vk/GrVkBuffer.h create mode 100644 libskia/src/gpu/vk/GrVkCaps.cpp create mode 100644 libskia/src/gpu/vk/GrVkCaps.h create mode 100644 libskia/src/gpu/vk/GrVkCommandBuffer.cpp create mode 100644 libskia/src/gpu/vk/GrVkCommandBuffer.h create mode 100644 libskia/src/gpu/vk/GrVkCopyManager.cpp create mode 100644 libskia/src/gpu/vk/GrVkCopyManager.h create mode 100644 libskia/src/gpu/vk/GrVkCopyPipeline.cpp create mode 100644 libskia/src/gpu/vk/GrVkCopyPipeline.h create mode 100644 libskia/src/gpu/vk/GrVkDescriptorPool.cpp create mode 100644 libskia/src/gpu/vk/GrVkDescriptorPool.h create mode 100644 libskia/src/gpu/vk/GrVkDescriptorSet.cpp create mode 100644 libskia/src/gpu/vk/GrVkDescriptorSet.h create mode 100644 libskia/src/gpu/vk/GrVkDescriptorSetManager.cpp create mode 100644 libskia/src/gpu/vk/GrVkDescriptorSetManager.h create mode 100644 libskia/src/gpu/vk/GrVkExtensions.cpp create mode 100644 libskia/src/gpu/vk/GrVkExtensions.h create mode 100644 libskia/src/gpu/vk/GrVkFramebuffer.cpp create mode 100644 libskia/src/gpu/vk/GrVkFramebuffer.h create mode 100644 libskia/src/gpu/vk/GrVkGpu.cpp create mode 100644 libskia/src/gpu/vk/GrVkGpu.h create mode 100644 libskia/src/gpu/vk/GrVkGpuCommandBuffer.cpp create mode 100644 libskia/src/gpu/vk/GrVkGpuCommandBuffer.h create mode 100644 libskia/src/gpu/vk/GrVkImage.cpp create mode 100644 libskia/src/gpu/vk/GrVkImage.h create mode 100644 libskia/src/gpu/vk/GrVkImageView.cpp create mode 100644 libskia/src/gpu/vk/GrVkImageView.h create mode 100644 libskia/src/gpu/vk/GrVkIndexBuffer.cpp create mode 100644 libskia/src/gpu/vk/GrVkIndexBuffer.h create mode 100644 libskia/src/gpu/vk/GrVkInterface.cpp create mode 100644 libskia/src/gpu/vk/GrVkMemory.cpp create mode 100644 libskia/src/gpu/vk/GrVkMemory.h create mode 100644 libskia/src/gpu/vk/GrVkPipeline.cpp create mode 100644 libskia/src/gpu/vk/GrVkPipeline.h create mode 100644 libskia/src/gpu/vk/GrVkPipelineState.cpp create mode 100644 libskia/src/gpu/vk/GrVkPipelineState.h create mode 100644 libskia/src/gpu/vk/GrVkPipelineStateBuilder.cpp create mode 100644 libskia/src/gpu/vk/GrVkPipelineStateBuilder.h create mode 100644 libskia/src/gpu/vk/GrVkPipelineStateCache.cpp create mode 100644 libskia/src/gpu/vk/GrVkPipelineStateDataManager.cpp create mode 100644 libskia/src/gpu/vk/GrVkPipelineStateDataManager.h create mode 100644 libskia/src/gpu/vk/GrVkRenderPass.cpp create mode 100644 libskia/src/gpu/vk/GrVkRenderPass.h create mode 100644 libskia/src/gpu/vk/GrVkRenderTarget.cpp create mode 100644 libskia/src/gpu/vk/GrVkRenderTarget.h create mode 100644 libskia/src/gpu/vk/GrVkResource.h create mode 100644 libskia/src/gpu/vk/GrVkResourceProvider.cpp create mode 100644 libskia/src/gpu/vk/GrVkResourceProvider.h create mode 100644 libskia/src/gpu/vk/GrVkSampler.cpp create mode 100644 libskia/src/gpu/vk/GrVkSampler.h create mode 100644 libskia/src/gpu/vk/GrVkStencilAttachment.cpp create mode 100644 libskia/src/gpu/vk/GrVkStencilAttachment.h create mode 100644 libskia/src/gpu/vk/GrVkTexture.cpp create mode 100644 libskia/src/gpu/vk/GrVkTexture.h create mode 100644 libskia/src/gpu/vk/GrVkTextureRenderTarget.cpp create mode 100644 libskia/src/gpu/vk/GrVkTextureRenderTarget.h create mode 100644 libskia/src/gpu/vk/GrVkTransferBuffer.cpp create mode 100644 libskia/src/gpu/vk/GrVkTransferBuffer.h create mode 100644 libskia/src/gpu/vk/GrVkUniformBuffer.cpp create mode 100644 libskia/src/gpu/vk/GrVkUniformBuffer.h create mode 100644 libskia/src/gpu/vk/GrVkUniformHandler.cpp create mode 100644 libskia/src/gpu/vk/GrVkUniformHandler.h create mode 100644 libskia/src/gpu/vk/GrVkUtil.cpp create mode 100644 libskia/src/gpu/vk/GrVkUtil.h create mode 100644 libskia/src/gpu/vk/GrVkVaryingHandler.cpp create mode 100644 libskia/src/gpu/vk/GrVkVaryingHandler.h create mode 100644 libskia/src/gpu/vk/GrVkVertexBuffer.cpp create mode 100644 libskia/src/gpu/vk/GrVkVertexBuffer.h delete mode 100644 libskia/src/image/SkImagePriv.cpp delete mode 100644 libskia/src/image/SkImagePriv.h create mode 100644 libskia/src/image/SkImageShader.cpp create mode 100644 libskia/src/image/SkImageShader.h create mode 100644 libskia/src/image/SkImageShaderContext.h delete mode 100644 libskia/src/image/SkImage_Codec.cpp create mode 100644 libskia/src/image/SkImage_Generator.cpp create mode 100644 libskia/src/image/SkImage_Gpu.h delete mode 100644 libskia/src/image/SkImage_Picture.cpp create mode 100644 libskia/src/image/SkReadPixelsRec.h create mode 100644 libskia/src/image/SkSurface_Gpu.h delete mode 100644 libskia/src/image/SkSurface_Picture.cpp delete mode 100644 libskia/src/images/SkDecodingImageGenerator.cpp delete mode 100644 libskia/src/images/SkDecodingImageGenerator.h delete mode 100644 libskia/src/images/SkForceLinking.cpp delete mode 100644 libskia/src/images/SkImageDecoder.cpp delete mode 100644 libskia/src/images/SkImageDecoder_FactoryDefault.cpp delete mode 100644 libskia/src/images/SkImageDecoder_FactoryRegistrar.cpp delete mode 100644 libskia/src/images/SkImageDecoder_libbmp.cpp delete mode 100644 libskia/src/images/SkImageDecoder_libgif.cpp delete mode 100644 libskia/src/images/SkImageDecoder_libico.cpp delete mode 100644 libskia/src/images/SkImageDecoder_libjpeg.cpp delete mode 100644 libskia/src/images/SkImageDecoder_libpng.cpp delete mode 100644 libskia/src/images/SkImageDecoder_libwebp.cpp delete mode 100644 libskia/src/images/SkImageDecoder_wbmp.cpp create mode 100644 libskia/src/images/SkImageEncoderPriv.h delete mode 100644 libskia/src/images/SkImageEncoder_Factory.cpp delete mode 100644 libskia/src/images/SkImageEncoder_argb.cpp delete mode 100644 libskia/src/images/SkImageRef.cpp delete mode 100644 libskia/src/images/SkImageRefPool.cpp delete mode 100644 libskia/src/images/SkImageRefPool.h delete mode 100644 libskia/src/images/SkImageRef_GlobalPool.cpp delete mode 100644 libskia/src/images/SkImageRef_ashmem.cpp delete mode 100644 libskia/src/images/SkImageRef_ashmem.h delete mode 100644 libskia/src/images/SkImages.cpp create mode 100644 libskia/src/images/SkJPEGImageEncoder.cpp create mode 100644 libskia/src/images/SkJPEGWriteUtility.cpp rename libskia/src/images/{SkJpegUtility.h => SkJPEGWriteUtility.h} (59%) delete mode 100644 libskia/src/images/SkJpegUtility.cpp create mode 100644 libskia/src/images/SkKTXImageEncoder.cpp delete mode 100644 libskia/src/images/SkMovie.cpp delete mode 100644 libskia/src/images/SkMovie_gif.cpp create mode 100644 libskia/src/images/SkPNGImageEncoder.cpp delete mode 100644 libskia/src/images/SkPageFlipper.cpp delete mode 100644 libskia/src/images/SkScaledBitmapSampler.cpp delete mode 100644 libskia/src/images/SkScaledBitmapSampler.h delete mode 100644 libskia/src/images/SkStreamHelpers.cpp delete mode 100644 libskia/src/images/SkStreamHelpers.h create mode 100644 libskia/src/images/SkWEBPImageEncoder.cpp delete mode 100644 libskia/src/images/bmpdecoderhelper.cpp delete mode 100644 libskia/src/images/bmpdecoderhelper.h create mode 100644 libskia/src/lazy/SkDiscardableMemoryPool.cpp create mode 100644 libskia/src/lazy/SkDiscardableMemoryPool.h create mode 100644 libskia/src/opts/Sk4px_NEON.h create mode 100644 libskia/src/opts/Sk4px_SSE2.h create mode 100644 libskia/src/opts/Sk4px_none.h create mode 100644 libskia/src/opts/SkBitmapFilter_opts.h delete mode 100644 libskia/src/opts/SkBitmapFilter_opts_SSE2.cpp delete mode 100644 libskia/src/opts/SkBitmapFilter_opts_SSE2.h delete mode 100644 libskia/src/opts/SkBitmapProcState_matrix_clamp_neon.h create mode 100644 libskia/src/opts/SkBitmapProcState_matrix_neon.h delete mode 100644 libskia/src/opts/SkBitmapProcState_matrix_repeat_neon.h delete mode 100644 libskia/src/opts/SkBitmapProcState_opts_arm.cpp create mode 100644 libskia/src/opts/SkBitmapProcState_opts_mips_dsp.cpp create mode 100644 libskia/src/opts/SkBlend_opts.h create mode 100644 libskia/src/opts/SkBlitMask_opts.h delete mode 100644 libskia/src/opts/SkBlitRect_opts_SSE2.cpp delete mode 100644 libskia/src/opts/SkBlitRect_opts_SSE2.h create mode 100644 libskia/src/opts/SkBlitRow_opts.h create mode 100644 libskia/src/opts/SkBlitRow_opts_mips_dsp.cpp create mode 100644 libskia/src/opts/SkBlurImageFilter_opts.h delete mode 100644 libskia/src/opts/SkBlurImage_opts.h delete mode 100644 libskia/src/opts/SkBlurImage_opts_SSE2.cpp delete mode 100644 libskia/src/opts/SkBlurImage_opts_SSE2.h delete mode 100644 libskia/src/opts/SkBlurImage_opts_neon.cpp delete mode 100644 libskia/src/opts/SkBlurImage_opts_neon.h delete mode 100644 libskia/src/opts/SkBlurImage_opts_none.cpp delete mode 100644 libskia/src/opts/SkCachePreload_arm.h create mode 100644 libskia/src/opts/SkChecksum_opts.h create mode 100644 libskia/src/opts/SkColorCubeFilter_opts.h create mode 100644 libskia/src/opts/SkColor_opts_SSE2.h create mode 100644 libskia/src/opts/SkMorphologyImageFilter_opts.h delete mode 100644 libskia/src/opts/SkMorphology_opts.h delete mode 100644 libskia/src/opts/SkMorphology_opts_SSE2.cpp delete mode 100644 libskia/src/opts/SkMorphology_opts_SSE2.h delete mode 100644 libskia/src/opts/SkMorphology_opts_neon.cpp delete mode 100644 libskia/src/opts/SkMorphology_opts_neon.h delete mode 100644 libskia/src/opts/SkMorphology_opts_none.cpp create mode 100644 libskia/src/opts/SkNx_neon.h create mode 100644 libskia/src/opts/SkNx_sse.h create mode 100644 libskia/src/opts/SkOpts_avx.cpp create mode 100644 libskia/src/opts/SkOpts_crc32.cpp create mode 100644 libskia/src/opts/SkOpts_hsw.cpp create mode 100644 libskia/src/opts/SkOpts_sse41.cpp create mode 100644 libskia/src/opts/SkOpts_sse42.cpp create mode 100644 libskia/src/opts/SkOpts_ssse3.cpp create mode 100644 libskia/src/opts/SkRasterPipeline_opts.h create mode 100644 libskia/src/opts/SkSwizzler_opts.h create mode 100644 libskia/src/opts/SkTextureCompressor_opts.h delete mode 100644 libskia/src/opts/SkUtils_opts_SSE2.cpp delete mode 100644 libskia/src/opts/SkUtils_opts_SSE2.h delete mode 100644 libskia/src/opts/SkUtils_opts_none.cpp create mode 100644 libskia/src/opts/SkXfermode_opts.h delete mode 100644 libskia/src/opts/SkXfermode_opts_arm.cpp delete mode 100644 libskia/src/opts/SkXfermode_opts_arm_neon.cpp delete mode 100644 libskia/src/opts/SkXfermode_opts_arm_neon.h delete mode 100644 libskia/src/opts/SkXfermode_opts_none.cpp delete mode 100644 libskia/src/opts/memset.arm.S delete mode 100644 libskia/src/opts/memset16_neon.S delete mode 100644 libskia/src/opts/memset32_neon.S delete mode 100644 libskia/src/opts/morphology_opts_check_mac.cpp delete mode 100644 libskia/src/opts/opts_check_SSE2.cpp delete mode 100644 libskia/src/opts/opts_check_arm.cpp delete mode 100644 libskia/src/opts/opts_check_mac.cpp create mode 100644 libskia/src/opts/opts_check_x86.cpp create mode 100644 libskia/src/pathops/SkDConicLineIntersection.cpp delete mode 100644 libskia/src/pathops/SkDCubicIntersection.cpp delete mode 100644 libskia/src/pathops/SkDQuadImplicit.cpp delete mode 100644 libskia/src/pathops/SkDQuadImplicit.h delete mode 100644 libskia/src/pathops/SkDQuadIntersection.cpp create mode 100644 libskia/src/pathops/SkOpBuilder.cpp create mode 100644 libskia/src/pathops/SkOpCoincidence.cpp create mode 100644 libskia/src/pathops/SkOpCoincidence.h create mode 100644 libskia/src/pathops/SkOpCubicHull.cpp create mode 100644 libskia/src/pathops/SkOpSpan.cpp create mode 100644 libskia/src/pathops/SkOpTAllocator.h delete mode 100644 libskia/src/pathops/SkPathOpsBounds.cpp create mode 100644 libskia/src/pathops/SkPathOpsConic.cpp create mode 100644 libskia/src/pathops/SkPathOpsConic.h create mode 100644 libskia/src/pathops/SkPathOpsCurve.cpp create mode 100644 libskia/src/pathops/SkPathOpsTSect.cpp create mode 100644 libskia/src/pathops/SkPathOpsTSect.h create mode 100644 libskia/src/pathops/SkPathOpsTightBounds.cpp delete mode 100644 libskia/src/pathops/SkPathOpsTriangle.cpp delete mode 100644 libskia/src/pathops/SkPathOpsTriangle.h create mode 100644 libskia/src/pathops/SkPathOpsWinding.cpp delete mode 100644 libskia/src/pathops/SkQuarticRoot.cpp delete mode 100644 libskia/src/pathops/SkQuarticRoot.h delete mode 100644 libskia/src/pathops/main.cpp create mode 100644 libskia/src/pdf/SkBitmapKey.h create mode 100644 libskia/src/pdf/SkDeflate.cpp create mode 100644 libskia/src/pdf/SkDeflate.h create mode 100644 libskia/src/pdf/SkDocument_PDF_None.cpp create mode 100644 libskia/src/pdf/SkJpegInfo.cpp create mode 100644 libskia/src/pdf/SkJpegInfo.h create mode 100644 libskia/src/pdf/SkPDFBitmap.cpp create mode 100644 libskia/src/pdf/SkPDFBitmap.h create mode 100644 libskia/src/pdf/SkPDFCanon.cpp create mode 100644 libskia/src/pdf/SkPDFCanon.h create mode 100644 libskia/src/pdf/SkPDFCanvas.cpp create mode 100644 libskia/src/pdf/SkPDFCanvas.h delete mode 100644 libskia/src/pdf/SkPDFCatalog.cpp delete mode 100644 libskia/src/pdf/SkPDFCatalog.h create mode 100644 libskia/src/pdf/SkPDFConvertType1FontStream.cpp create mode 100644 libskia/src/pdf/SkPDFConvertType1FontStream.h create mode 100644 libskia/src/pdf/SkPDFDevice.h delete mode 100644 libskia/src/pdf/SkPDFDeviceFlattener.cpp delete mode 100644 libskia/src/pdf/SkPDFDeviceFlattener.h create mode 100644 libskia/src/pdf/SkPDFDocument.h delete mode 100755 libskia/src/pdf/SkPDFFontImpl.h delete mode 100644 libskia/src/pdf/SkPDFImage.cpp delete mode 100644 libskia/src/pdf/SkPDFImage.h create mode 100644 libskia/src/pdf/SkPDFMakeCIDGlyphWidthsArray.cpp create mode 100644 libskia/src/pdf/SkPDFMakeCIDGlyphWidthsArray.h create mode 100644 libskia/src/pdf/SkPDFMakeToUnicodeCmap.cpp create mode 100644 libskia/src/pdf/SkPDFMakeToUnicodeCmap.h create mode 100644 libskia/src/pdf/SkPDFMetadata.cpp create mode 100644 libskia/src/pdf/SkPDFMetadata.h delete mode 100644 libskia/src/pdf/SkPDFPage.cpp delete mode 100644 libskia/src/pdf/SkPDFPage.h delete mode 100644 libskia/src/pdf/SkPDFStream.cpp delete mode 100644 libskia/src/pdf/SkPDFStream.h create mode 100644 libskia/src/pdf/SkScopeExit.h delete mode 100644 libskia/src/pdf/SkTSet.h delete mode 100644 libskia/src/pipe/SkGPipePriv.h delete mode 100644 libskia/src/pipe/SkGPipeRead.cpp delete mode 100644 libskia/src/pipe/SkGPipeWrite.cpp create mode 100644 libskia/src/pipe/SkPipeCanvas.cpp create mode 100644 libskia/src/pipe/SkPipeCanvas.h create mode 100644 libskia/src/pipe/SkPipeFormat.h create mode 100644 libskia/src/pipe/SkPipeReader.cpp create mode 100644 libskia/src/pipe/SkRefSet.h delete mode 100644 libskia/src/pipe/utils/SamplePipeControllers.cpp delete mode 100644 libskia/src/pipe/utils/SamplePipeControllers.h delete mode 100644 libskia/src/ports/SkAtomics_android.h delete mode 100644 libskia/src/ports/SkAtomics_none.h delete mode 100644 libskia/src/ports/SkAtomics_sync.h delete mode 100644 libskia/src/ports/SkAtomics_win.h delete mode 100644 libskia/src/ports/SkDebug_nacl.cpp delete mode 100644 libskia/src/ports/SkDiscardableMemory_ashmem.cpp create mode 100644 libskia/src/ports/SkFontConfigInterface.cpp delete mode 100644 libskia/src/ports/SkFontConfigInterface_android.cpp create mode 100644 libskia/src/ports/SkFontConfigInterface_direct.h create mode 100644 libskia/src/ports/SkFontConfigInterface_direct_factory.cpp delete mode 100644 libskia/src/ports/SkFontConfigParser_android.cpp delete mode 100644 libskia/src/ports/SkFontConfigParser_android.h delete mode 100644 libskia/src/ports/SkFontHost_android.cpp delete mode 100644 libskia/src/ports/SkFontHost_fontconfig.cpp delete mode 100644 libskia/src/ports/SkFontHost_linux.cpp mode change 100755 => 100644 libskia/src/ports/SkFontHost_mac.cpp mode change 100755 => 100644 libskia/src/ports/SkFontHost_win.cpp delete mode 100644 libskia/src/ports/SkFontHost_win_dw.cpp create mode 100644 libskia/src/ports/SkFontMgr_FontConfigInterface.cpp create mode 100644 libskia/src/ports/SkFontMgr_FontConfigInterface_factory.cpp create mode 100644 libskia/src/ports/SkFontMgr_android.cpp create mode 100644 libskia/src/ports/SkFontMgr_android_factory.cpp create mode 100644 libskia/src/ports/SkFontMgr_android_parser.cpp create mode 100644 libskia/src/ports/SkFontMgr_android_parser.h create mode 100644 libskia/src/ports/SkFontMgr_custom.cpp create mode 100644 libskia/src/ports/SkFontMgr_custom_directory_factory.cpp create mode 100644 libskia/src/ports/SkFontMgr_custom_embedded_factory.cpp create mode 100644 libskia/src/ports/SkFontMgr_custom_empty_factory.cpp delete mode 100644 libskia/src/ports/SkFontMgr_default_dw.cpp delete mode 100644 libskia/src/ports/SkFontMgr_default_gdi.cpp rename libskia/src/ports/{SkFontHost_none.cpp => SkFontMgr_empty_factory.cpp} (67%) create mode 100644 libskia/src/ports/SkFontMgr_fontconfig.cpp create mode 100644 libskia/src/ports/SkFontMgr_fontconfig_factory.cpp create mode 100644 libskia/src/ports/SkFontMgr_win_dw.cpp create mode 100644 libskia/src/ports/SkFontMgr_win_dw_factory.cpp create mode 100644 libskia/src/ports/SkFontMgr_win_gdi_factory.cpp delete mode 100644 libskia/src/ports/SkGlobalInitialization_chromium.cpp delete mode 100644 libskia/src/ports/SkHarfBuzzFont.cpp delete mode 100644 libskia/src/ports/SkImageDecoder_CG.cpp delete mode 100644 libskia/src/ports/SkImageDecoder_WIC.cpp delete mode 100644 libskia/src/ports/SkImageDecoder_empty.cpp create mode 100644 libskia/src/ports/SkImageEncoder_CG.cpp create mode 100644 libskia/src/ports/SkImageEncoder_WIC.cpp rename libskia/src/{svg/SkSVGG.cpp => ports/SkImageEncoder_none.cpp} (53%) create mode 100644 libskia/src/ports/SkImageGeneratorCG.cpp create mode 100644 libskia/src/ports/SkImageGeneratorCG.h create mode 100644 libskia/src/ports/SkImageGeneratorWIC.cpp create mode 100644 libskia/src/ports/SkImageGeneratorWIC.h create mode 100644 libskia/src/ports/SkImageGenerator_none.cpp create mode 100644 libskia/src/ports/SkImageGenerator_skia.cpp delete mode 100644 libskia/src/ports/SkMutex_none.h delete mode 100644 libskia/src/ports/SkMutex_pthread.h delete mode 100644 libskia/src/ports/SkMutex_win.h delete mode 100644 libskia/src/ports/SkOSFile_none.cpp create mode 100644 libskia/src/ports/SkOSLibrary.h create mode 100644 libskia/src/ports/SkOSLibrary_posix.cpp create mode 100644 libskia/src/ports/SkOSLibrary_win.cpp delete mode 100644 libskia/src/ports/SkPurgeableMemoryBlock_android.cpp delete mode 100644 libskia/src/ports/SkPurgeableMemoryBlock_mac.cpp delete mode 100644 libskia/src/ports/SkPurgeableMemoryBlock_none.cpp create mode 100644 libskia/src/ports/SkRemotableFontMgr_win_dw.cpp create mode 100644 libskia/src/ports/SkScalerContext_win_dw.cpp create mode 100644 libskia/src/ports/SkScalerContext_win_dw.h delete mode 100644 libskia/src/ports/SkTime_Unix.cpp delete mode 100644 libskia/src/ports/SkTime_win.cpp create mode 100644 libskia/src/ports/SkTypeface_win_dw.cpp create mode 100644 libskia/src/ports/SkTypeface_win_dw.h delete mode 100644 libskia/src/ports/SkXMLParser_empty.cpp delete mode 100644 libskia/src/ports/SkXMLParser_expat.cpp delete mode 100644 libskia/src/ports/SkXMLParser_tinyxml.cpp delete mode 100644 libskia/src/ports/SkXMLPullParser_expat.cpp create mode 100644 libskia/src/ports/android-cpu-features.c create mode 100644 libskia/src/sfnt/SkOTTable_EBDT.h create mode 100644 libskia/src/sfnt/SkOTTable_EBLC.h create mode 100644 libskia/src/sfnt/SkOTTable_EBSC.h create mode 100644 libskia/src/sfnt/SkOTTable_gasp.h delete mode 100644 libskia/src/sfnt/SkPreprocessorSeq.h delete mode 100644 libskia/src/sfnt/SkTypedEnum.h create mode 100644 libskia/src/sksl/GLSL.std.450.h create mode 100644 libskia/src/sksl/SkSLCFGGenerator.cpp create mode 100644 libskia/src/sksl/SkSLCFGGenerator.h create mode 100644 libskia/src/sksl/SkSLCodeGenerator.h create mode 100644 libskia/src/sksl/SkSLCompiler.cpp create mode 100644 libskia/src/sksl/SkSLCompiler.h create mode 100644 libskia/src/sksl/SkSLContext.h create mode 100644 libskia/src/sksl/SkSLErrorReporter.h create mode 100644 libskia/src/sksl/SkSLGLSLCodeGenerator.cpp create mode 100644 libskia/src/sksl/SkSLGLSLCodeGenerator.h create mode 100644 libskia/src/sksl/SkSLIRGenerator.cpp create mode 100644 libskia/src/sksl/SkSLIRGenerator.h create mode 100644 libskia/src/sksl/SkSLMain.cpp create mode 100644 libskia/src/sksl/SkSLMemoryLayout.h create mode 100644 libskia/src/sksl/SkSLParser.cpp create mode 100644 libskia/src/sksl/SkSLParser.h create mode 100644 libskia/src/sksl/SkSLPosition.h create mode 100644 libskia/src/sksl/SkSLSPIRVCodeGenerator.cpp create mode 100644 libskia/src/sksl/SkSLSPIRVCodeGenerator.h create mode 100644 libskia/src/sksl/SkSLToken.h create mode 100644 libskia/src/sksl/SkSLUtil.cpp create mode 100644 libskia/src/sksl/SkSLUtil.h create mode 100644 libskia/src/sksl/ast/SkSLASTBinaryExpression.h create mode 100644 libskia/src/sksl/ast/SkSLASTBlock.h create mode 100644 libskia/src/sksl/ast/SkSLASTBoolLiteral.h create mode 100644 libskia/src/sksl/ast/SkSLASTBreakStatement.h create mode 100644 libskia/src/sksl/ast/SkSLASTCallSuffix.h create mode 100644 libskia/src/sksl/ast/SkSLASTContinueStatement.h create mode 100644 libskia/src/sksl/ast/SkSLASTDeclaration.h create mode 100644 libskia/src/sksl/ast/SkSLASTDiscardStatement.h create mode 100644 libskia/src/sksl/ast/SkSLASTDoStatement.h create mode 100644 libskia/src/sksl/ast/SkSLASTExpression.h create mode 100644 libskia/src/sksl/ast/SkSLASTExpressionStatement.h create mode 100644 libskia/src/sksl/ast/SkSLASTExtension.h create mode 100644 libskia/src/sksl/ast/SkSLASTFieldSuffix.h create mode 100644 libskia/src/sksl/ast/SkSLASTFloatLiteral.h create mode 100644 libskia/src/sksl/ast/SkSLASTForStatement.h create mode 100644 libskia/src/sksl/ast/SkSLASTFunction.h create mode 100644 libskia/src/sksl/ast/SkSLASTIdentifier.h create mode 100644 libskia/src/sksl/ast/SkSLASTIfStatement.h create mode 100644 libskia/src/sksl/ast/SkSLASTIndexSuffix.h create mode 100644 libskia/src/sksl/ast/SkSLASTIntLiteral.h create mode 100644 libskia/src/sksl/ast/SkSLASTInterfaceBlock.h create mode 100644 libskia/src/sksl/ast/SkSLASTModifiersDeclaration.h create mode 100644 libskia/src/sksl/ast/SkSLASTNode.h create mode 100644 libskia/src/sksl/ast/SkSLASTParameter.h create mode 100644 libskia/src/sksl/ast/SkSLASTPositionNode.h create mode 100644 libskia/src/sksl/ast/SkSLASTPrecision.h create mode 100644 libskia/src/sksl/ast/SkSLASTPrefixExpression.h create mode 100644 libskia/src/sksl/ast/SkSLASTReturnStatement.h create mode 100644 libskia/src/sksl/ast/SkSLASTStatement.h create mode 100644 libskia/src/sksl/ast/SkSLASTSuffix.h create mode 100644 libskia/src/sksl/ast/SkSLASTSuffixExpression.h create mode 100644 libskia/src/sksl/ast/SkSLASTTernaryExpression.h create mode 100644 libskia/src/sksl/ast/SkSLASTType.h create mode 100644 libskia/src/sksl/ast/SkSLASTVarDeclaration.h create mode 100644 libskia/src/sksl/ast/SkSLASTVarDeclarationStatement.h create mode 100644 libskia/src/sksl/ast/SkSLASTWhileStatement.h create mode 100644 libskia/src/sksl/ir/SkSLBinaryExpression.h create mode 100644 libskia/src/sksl/ir/SkSLBlock.h create mode 100644 libskia/src/sksl/ir/SkSLBoolLiteral.h create mode 100644 libskia/src/sksl/ir/SkSLBreakStatement.h create mode 100644 libskia/src/sksl/ir/SkSLConstructor.h create mode 100644 libskia/src/sksl/ir/SkSLContinueStatement.h create mode 100644 libskia/src/sksl/ir/SkSLDiscardStatement.h create mode 100644 libskia/src/sksl/ir/SkSLDoStatement.h create mode 100644 libskia/src/sksl/ir/SkSLExpression.h create mode 100644 libskia/src/sksl/ir/SkSLExpressionStatement.h create mode 100644 libskia/src/sksl/ir/SkSLExtension.h create mode 100644 libskia/src/sksl/ir/SkSLField.h create mode 100644 libskia/src/sksl/ir/SkSLFieldAccess.h create mode 100644 libskia/src/sksl/ir/SkSLFloatLiteral.h create mode 100644 libskia/src/sksl/ir/SkSLForStatement.h create mode 100644 libskia/src/sksl/ir/SkSLFunctionCall.h create mode 100644 libskia/src/sksl/ir/SkSLFunctionDeclaration.h create mode 100644 libskia/src/sksl/ir/SkSLFunctionDefinition.h create mode 100644 libskia/src/sksl/ir/SkSLFunctionReference.h create mode 100644 libskia/src/sksl/ir/SkSLIRNode.h create mode 100644 libskia/src/sksl/ir/SkSLIfStatement.h create mode 100644 libskia/src/sksl/ir/SkSLIndexExpression.h create mode 100644 libskia/src/sksl/ir/SkSLIntLiteral.h create mode 100644 libskia/src/sksl/ir/SkSLInterfaceBlock.h create mode 100644 libskia/src/sksl/ir/SkSLLayout.h create mode 100644 libskia/src/sksl/ir/SkSLModifiers.h create mode 100644 libskia/src/sksl/ir/SkSLModifiersDeclaration.h create mode 100644 libskia/src/sksl/ir/SkSLPostfixExpression.h create mode 100644 libskia/src/sksl/ir/SkSLPrefixExpression.h create mode 100644 libskia/src/sksl/ir/SkSLProgram.h create mode 100644 libskia/src/sksl/ir/SkSLProgramElement.h create mode 100644 libskia/src/sksl/ir/SkSLReturnStatement.h create mode 100644 libskia/src/sksl/ir/SkSLStatement.h create mode 100644 libskia/src/sksl/ir/SkSLSwizzle.h create mode 100644 libskia/src/sksl/ir/SkSLSymbol.h create mode 100644 libskia/src/sksl/ir/SkSLSymbolTable.cpp create mode 100644 libskia/src/sksl/ir/SkSLSymbolTable.h create mode 100644 libskia/src/sksl/ir/SkSLTernaryExpression.h create mode 100644 libskia/src/sksl/ir/SkSLType.cpp create mode 100644 libskia/src/sksl/ir/SkSLType.h create mode 100644 libskia/src/sksl/ir/SkSLTypeReference.h create mode 100644 libskia/src/sksl/ir/SkSLUnresolvedFunction.h create mode 100644 libskia/src/sksl/ir/SkSLVarDeclarations.h create mode 100644 libskia/src/sksl/ir/SkSLVarDeclarationsStatement.h create mode 100644 libskia/src/sksl/ir/SkSLVariable.h create mode 100644 libskia/src/sksl/ir/SkSLVariableReference.h create mode 100644 libskia/src/sksl/ir/SkSLWhileStatement.h create mode 100644 libskia/src/sksl/lex.sksl.c create mode 100644 libskia/src/sksl/readme create mode 100644 libskia/src/sksl/sksl.include create mode 100644 libskia/src/sksl/sksl_frag.include create mode 100644 libskia/src/sksl/sksl_vert.include create mode 100644 libskia/src/sksl/spirv.h delete mode 100644 libskia/src/svg/SkSVG.cpp create mode 100644 libskia/src/svg/SkSVGCanvas.cpp delete mode 100644 libskia/src/svg/SkSVGCircle.cpp delete mode 100644 libskia/src/svg/SkSVGCircle.h delete mode 100644 libskia/src/svg/SkSVGClipPath.cpp delete mode 100644 libskia/src/svg/SkSVGClipPath.h delete mode 100644 libskia/src/svg/SkSVGDefs.h create mode 100644 libskia/src/svg/SkSVGDevice.cpp create mode 100644 libskia/src/svg/SkSVGDevice.h delete mode 100644 libskia/src/svg/SkSVGElements.cpp delete mode 100644 libskia/src/svg/SkSVGElements.h delete mode 100644 libskia/src/svg/SkSVGEllipse.cpp delete mode 100644 libskia/src/svg/SkSVGEllipse.h delete mode 100644 libskia/src/svg/SkSVGFeColorMatrix.cpp delete mode 100644 libskia/src/svg/SkSVGFeColorMatrix.h delete mode 100644 libskia/src/svg/SkSVGFilter.cpp delete mode 100644 libskia/src/svg/SkSVGFilter.h delete mode 100644 libskia/src/svg/SkSVGG.h delete mode 100644 libskia/src/svg/SkSVGGradient.cpp delete mode 100644 libskia/src/svg/SkSVGGradient.h delete mode 100644 libskia/src/svg/SkSVGGroup.cpp delete mode 100644 libskia/src/svg/SkSVGGroup.h delete mode 100644 libskia/src/svg/SkSVGImage.cpp delete mode 100644 libskia/src/svg/SkSVGImage.h delete mode 100644 libskia/src/svg/SkSVGLine.cpp delete mode 100644 libskia/src/svg/SkSVGLine.h delete mode 100644 libskia/src/svg/SkSVGLinearGradient.cpp delete mode 100644 libskia/src/svg/SkSVGLinearGradient.h delete mode 100644 libskia/src/svg/SkSVGMask.cpp delete mode 100644 libskia/src/svg/SkSVGMask.h delete mode 100644 libskia/src/svg/SkSVGMetadata.cpp delete mode 100644 libskia/src/svg/SkSVGMetadata.h delete mode 100644 libskia/src/svg/SkSVGPaintState.cpp delete mode 100644 libskia/src/svg/SkSVGParser.cpp delete mode 100644 libskia/src/svg/SkSVGPath.cpp delete mode 100644 libskia/src/svg/SkSVGPath.h delete mode 100644 libskia/src/svg/SkSVGPolygon.cpp delete mode 100644 libskia/src/svg/SkSVGPolygon.h delete mode 100644 libskia/src/svg/SkSVGPolyline.cpp delete mode 100644 libskia/src/svg/SkSVGPolyline.h delete mode 100644 libskia/src/svg/SkSVGRadialGradient.cpp delete mode 100644 libskia/src/svg/SkSVGRadialGradient.h delete mode 100644 libskia/src/svg/SkSVGRect.cpp delete mode 100644 libskia/src/svg/SkSVGRect.h delete mode 100644 libskia/src/svg/SkSVGSVG.cpp delete mode 100644 libskia/src/svg/SkSVGSVG.h delete mode 100644 libskia/src/svg/SkSVGStop.cpp delete mode 100644 libskia/src/svg/SkSVGStop.h delete mode 100644 libskia/src/svg/SkSVGSymbol.cpp delete mode 100644 libskia/src/svg/SkSVGSymbol.h delete mode 100644 libskia/src/svg/SkSVGText.cpp delete mode 100644 libskia/src/svg/SkSVGText.h delete mode 100644 libskia/src/svg/SkSVGUse.cpp delete mode 100644 libskia/src/svg/SkSVGUse.h delete mode 100644 libskia/src/text/SkTextLayout.cpp delete mode 100755 libskia/src/utils/SkBitSet.cpp mode change 100755 => 100644 libskia/src/utils/SkBitSet.h delete mode 100644 libskia/src/utils/SkBitmapHasher.cpp delete mode 100644 libskia/src/utils/SkBitmapHasher.h create mode 100644 libskia/src/utils/SkBitmapSourceDeserializer.cpp create mode 100644 libskia/src/utils/SkBitmapSourceDeserializer.h delete mode 100644 libskia/src/utils/SkCondVar.cpp delete mode 100644 libskia/src/utils/SkCountdown.cpp delete mode 100644 libskia/src/utils/SkCubicInterval.cpp delete mode 100644 libskia/src/utils/SkCullPoints.cpp create mode 100644 libskia/src/utils/SkCurveMeasure.cpp create mode 100644 libskia/src/utils/SkCurveMeasure.h create mode 100644 libskia/src/utils/SkDashPath.cpp create mode 100644 libskia/src/utils/SkDashPathPriv.h delete mode 100644 libskia/src/utils/SkDebugTrace.h create mode 100644 libskia/src/utils/SkDeferredCanvas.h create mode 100644 libskia/src/utils/SkEventTracer.cpp delete mode 100644 libskia/src/utils/SkJSON.cpp delete mode 100644 libskia/src/utils/SkMD5.h create mode 100644 libskia/src/utils/SkMatrix22.cpp create mode 100644 libskia/src/utils/SkMatrix22.h create mode 100644 libskia/src/utils/SkMultiPictureDocument.cpp create mode 100644 libskia/src/utils/SkMultiPictureDocument.h create mode 100644 libskia/src/utils/SkMultiPictureDocumentPriv.h create mode 100644 libskia/src/utils/SkMultiPictureDocumentReader.cpp create mode 100644 libskia/src/utils/SkMultiPictureDocumentReader.h delete mode 100644 libskia/src/utils/SkNinePatch.cpp delete mode 100644 libskia/src/utils/SkOSFile.cpp create mode 100644 libskia/src/utils/SkOSPath.cpp create mode 100644 libskia/src/utils/SkOSPath.h delete mode 100644 libskia/src/utils/SkPDFRasterizer.cpp delete mode 100644 libskia/src/utils/SkPDFRasterizer.h create mode 100644 libskia/src/utils/SkPaintFilterCanvas.cpp create mode 100644 libskia/src/utils/SkPatchGrid.cpp create mode 100644 libskia/src/utils/SkPatchGrid.h create mode 100644 libskia/src/utils/SkPatchUtils.cpp create mode 100644 libskia/src/utils/SkPatchUtils.h delete mode 100644 libskia/src/utils/SkPathUtils.cpp delete mode 100644 libskia/src/utils/SkPictureUtils.cpp delete mode 100644 libskia/src/utils/SkProxyCanvas.cpp create mode 100644 libskia/src/utils/SkRGBAToYUV.cpp create mode 100644 libskia/src/utils/SkRGBAToYUV.h delete mode 100644 libskia/src/utils/SkRTConf.cpp delete mode 100644 libskia/src/utils/SkSHA1.cpp delete mode 100644 libskia/src/utils/SkSHA1.h create mode 100644 libskia/src/utils/SkShadowPaintFilterCanvas.cpp create mode 100644 libskia/src/utils/SkShadowPaintFilterCanvas.h delete mode 100644 libskia/src/utils/SkTFitsIn.h delete mode 100644 libskia/src/utils/SkTLogic.h create mode 100644 libskia/src/utils/SkTextBox.cpp create mode 100644 libskia/src/utils/SkTextureCompressor.cpp create mode 100644 libskia/src/utils/SkTextureCompressor.h create mode 100644 libskia/src/utils/SkTextureCompressor_ASTC.cpp create mode 100644 libskia/src/utils/SkTextureCompressor_ASTC.h create mode 100644 libskia/src/utils/SkTextureCompressor_Blitter.h create mode 100644 libskia/src/utils/SkTextureCompressor_LATC.cpp create mode 100644 libskia/src/utils/SkTextureCompressor_LATC.h create mode 100644 libskia/src/utils/SkTextureCompressor_R11EAC.cpp create mode 100644 libskia/src/utils/SkTextureCompressor_R11EAC.h create mode 100644 libskia/src/utils/SkTextureCompressor_Utils.h delete mode 100644 libskia/src/utils/SkThreadPool.cpp delete mode 100644 libskia/src/utils/SkThreadUtils_pthread_linux.cpp delete mode 100644 libskia/src/utils/SkThreadUtils_pthread_mach.cpp delete mode 100644 libskia/src/utils/SkThreadUtils_pthread_other.cpp delete mode 100644 libskia/src/utils/SkUnitMappers.cpp create mode 100644 libskia/src/utils/SkWhitelistChecksums.inc create mode 100644 libskia/src/utils/SkWhitelistTypefaces.cpp delete mode 100644 libskia/src/utils/android/ashmem.cpp delete mode 100644 libskia/src/utils/android/ashmem.h delete mode 100644 libskia/src/utils/debugger/SkDebugCanvas.cpp delete mode 100644 libskia/src/utils/debugger/SkDebugCanvas.h delete mode 100644 libskia/src/utils/debugger/SkDrawCommand.cpp delete mode 100644 libskia/src/utils/debugger/SkDrawCommand.h delete mode 100644 libskia/src/utils/debugger/SkObjectParser.cpp delete mode 100644 libskia/src/utils/debugger/SkObjectParser.h delete mode 100755 libskia/src/utils/ios/SkFontHost_iOS.mm delete mode 100755 libskia/src/utils/ios/SkImageDecoder_iOS.mm delete mode 100755 libskia/src/utils/ios/SkOSFile_iOS.mm delete mode 100755 libskia/src/utils/ios/SkStream_NSData.mm rename libskia/{include => src}/utils/win/SkAutoCoInitialize.h (78%) create mode 100644 libskia/src/utils/win/SkDWrite.cpp create mode 100644 libskia/src/utils/win/SkDWrite.h rename libskia/{include => src}/utils/win/SkHRESULT.h (71%) rename libskia/{include => src}/utils/win/SkIStream.h (91%) rename libskia/{include => src}/utils/win/SkTScopedComPtr.h (67%) rename libskia/{include/utils => src/utils/win}/SkWGL.h (61%) create mode 100644 libskia/src/views/SkEvent.cpp create mode 100644 libskia/src/views/SkEventSink.cpp create mode 100644 libskia/src/views/SkOSMenu.cpp create mode 100644 libskia/src/views/SkTagList.cpp create mode 100644 libskia/src/views/SkTagList.h create mode 100644 libskia/src/views/SkTouchGesture.cpp create mode 100644 libskia/src/views/SkView.cpp create mode 100644 libskia/src/views/SkViewPriv.cpp create mode 100644 libskia/src/views/SkViewPriv.h create mode 100644 libskia/src/views/SkWindow.cpp create mode 100644 libskia/src/views/mac/SkEventNotifier.h create mode 100644 libskia/src/views/mac/SkNSView.h create mode 100644 libskia/src/views/mac/SkOptionsTableView.h rename libskia/src/{gpu/gl/SkNullGLContext.cpp => views/mac/SkSampleNSView.h} (52%) create mode 100644 libskia/src/views/mac/SkTextFieldCell.h create mode 100644 libskia/src/views/sdl/SkOSWindow_SDL.cpp create mode 100644 libskia/src/views/unix/SkOSWindow_Unix.cpp create mode 100644 libskia/src/views/unix/XkeysToSkKeys.h create mode 100644 libskia/src/views/unix/keysym2ucs.h create mode 100644 libskia/src/views/unix/skia_unix.cpp create mode 100644 libskia/src/views/win/SkOSWindow_win.cpp create mode 100644 libskia/src/views/win/skia_win.cpp create mode 100644 libskia/src/xml/SkDOM.cpp create mode 100644 libskia/src/xml/SkXMLParser.cpp create mode 100644 libskia/src/xml/SkXMLWriter.cpp create mode 100644 libskia/src/xps/SkDocument_XPS.cpp create mode 100644 libskia/src/xps/SkDocument_XPS_None.cpp rename libskia/src/{device => }/xps/SkXPSDevice.cpp (79%) rename libskia/{include/device => src}/xps/SkXPSDevice.h (84%) diff --git a/libskia/git-revision.txt b/libskia/git-revision.txt new file mode 100755 index 00000000..95e0df68 --- /dev/null +++ b/libskia/git-revision.txt @@ -0,0 +1 @@ +20471894eaa441193d5ae8f2395e8244c91c55af diff --git a/libskia/include/android/SkBRDAllocator.h b/libskia/include/android/SkBRDAllocator.h new file mode 100644 index 00000000..3ca30c9b --- /dev/null +++ b/libskia/include/android/SkBRDAllocator.h @@ -0,0 +1,29 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkBRDAllocator_DEFINED +#define SkBRDAllocator_DEFINED + +#include "SkBitmap.h" +#include "SkCodec.h" + +/** + * Abstract subclass of SkBitmap's allocator. + * Allows the allocator to indicate if the memory it allocates + * is zero initialized. + */ +class SkBRDAllocator : public SkBitmap::Allocator { +public: + + /** + * Indicates if the memory allocated by this allocator is + * zero initialized. + */ + virtual SkCodec::ZeroInitialized zeroInit() const = 0; +}; + +#endif // SkBRDAllocator_DEFINED diff --git a/libskia/include/android/SkBitmapRegionDecoder.h b/libskia/include/android/SkBitmapRegionDecoder.h new file mode 100644 index 00000000..660aa0ae --- /dev/null +++ b/libskia/include/android/SkBitmapRegionDecoder.h @@ -0,0 +1,88 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkBitmapRegionDecoder_DEFINED +#define SkBitmapRegionDecoder_DEFINED + +#include "SkBitmap.h" +#include "SkBRDAllocator.h" +#include "SkEncodedImageFormat.h" +#include "SkStream.h" + +/* + * This class aims to provide an interface to test multiple implementations of + * SkBitmapRegionDecoder. + */ +class SkBitmapRegionDecoder { +public: + + enum Strategy { + kAndroidCodec_Strategy, // Uses SkAndroidCodec for scaling and subsetting + }; + + /* + * @param data Refs the data while this object exists, unrefs on destruction + * @param strategy Strategy used for scaling and subsetting + * @return Tries to create an SkBitmapRegionDecoder, returns NULL on failure + */ + static SkBitmapRegionDecoder* Create(sk_sp, Strategy strategy); + + /* + * @param stream Takes ownership of the stream + * @param strategy Strategy used for scaling and subsetting + * @return Tries to create an SkBitmapRegionDecoder, returns NULL on failure + */ + static SkBitmapRegionDecoder* Create( + SkStreamRewindable* stream, Strategy strategy); + + /* + * Decode a scaled region of the encoded image stream + * + * @param bitmap Container for decoded pixels. It is assumed that the pixels + * are initially unallocated and will be allocated by this function. + * @param allocator Allocator for the pixels. If this is NULL, the default + * allocator (HeapAllocator) will be used. + * @param desiredSubset Subset of the original image to decode. + * @param sampleSize An integer downscaling factor for the decode. + * @param colorType Preferred output colorType. + * New implementations should return NULL if they do not support + * decoding to this color type. + * The old kOriginal_Strategy will decode to a default color type + * if this color type is unsupported. + * @param requireUnpremul If the image is not opaque, we will use this to determine the + * alpha type to use. + * + */ + virtual bool decodeRegion(SkBitmap* bitmap, SkBRDAllocator* allocator, + const SkIRect& desiredSubset, int sampleSize, + SkColorType colorType, bool requireUnpremul) = 0; + /* + * @param Requested destination color type + * @return true if we support the requested color type and false otherwise + */ + virtual bool conversionSupported(SkColorType colorType) = 0; + + virtual SkEncodedImageFormat getEncodedFormat() = 0; + + int width() const { return fWidth; } + int height() const { return fHeight; } + + virtual ~SkBitmapRegionDecoder() {} + +protected: + + SkBitmapRegionDecoder(int width, int height) + : fWidth(width) + , fHeight(height) + {} + +private: + const int fWidth; + const int fHeight; +}; + +#endif diff --git a/libskia/include/animator/SkAnimator.h b/libskia/include/animator/SkAnimator.h new file mode 100644 index 00000000..0fe787c5 --- /dev/null +++ b/libskia/include/animator/SkAnimator.h @@ -0,0 +1,501 @@ + +/* + * Copyright 2006 The Android Open Source Project + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + + +#ifndef SkAnimator_DEFINED +#define SkAnimator_DEFINED + +#include "SkScalar.h" +#include "SkKey.h" +#include "SkEventSink.h" + +class SkAnimateMaker; +class SkCanvas; +class SkDisplayable; +class SkEvent; +class SkExtras; +struct SkMemberInfo; +class SkPaint; +struct SkRect; +class SkStream; +class SkTypedArray; +class SkXMLParserError; +class SkDOM; +struct SkDOMNode; + +/** SkElementType is the type of element: a rectangle, a color, an animator, and so on. + This enum is incomplete and will be fleshed out in a future release */ +enum SkElementType { + kElementDummyType +}; +/** SkFieldType is the type of field: a scalar, a string, an integer, a boolean, and so on. + This enum is incomplete and will be fleshed out in a future release */ +enum SkFieldType { + kFieldDummyType +}; + +/** \class SkAnimator + + The SkAnimator class decodes an XML stream into a display list. The + display list can be drawn statically as a picture, or can drawn + different elements at different times to form a moving animation. + + SkAnimator does not read the system time on its own; it relies on the + caller to pass the current time. The caller can pause, speed up, or + reverse the animation by varying the time passed in. + + The XML describing the display list must conform to the schema + described by SkAnimateSchema.xsd. + + The XML must contain an element to draw. Usually, it contains + an block to add some drawing elements to the + display list when the document is first decoded. + + Here's an "Hello World" XML sample: + + + + + + + + To read and draw this sample: + + // choose one of these two + SkAnimator animator; // declare an animator instance on the stack + // SkAnimator* animator = new SkAnimator() // or one could instantiate the class + + // choose one of these three + animator.decodeMemory(buffer, size); // to read from RAM + animator.decodeStream(stream); // to read from a user-defined stream (e.g., a zip file) + animator.decodeURI(filename); // to read from a web location, or from a local text file + + // to draw to the current window: + SkCanvas canvas(getBitmap()); // create a canvas + animator.draw(canvas, &paint, 0); // draw the scene +*/ +class SkAnimator : public SkEventSink { +public: + SkAnimator(); + virtual ~SkAnimator(); + + /** Add a drawable extension to the graphics engine. Experimental. + @param extras A derived class that implements methods that identify and instantiate the class + */ + void addExtras(SkExtras* extras); + + /** Read in XML from a stream, and append it to the current + animator. Returns false if an error was encountered. + Error diagnostics are stored in fErrorCode and fLineNumber. + @param stream The stream to append. + @return true if the XML was parsed successfully. + */ + bool appendStream(SkStream* stream); + + /** Read in XML from memory. Returns true if the file can be + read without error. Returns false if an error was encountered. + Error diagnostics are stored in fErrorCode and fLineNumber. + @param buffer The XML text as UTF-8 characters. + @param size The XML text length in bytes. + @return true if the XML was parsed successfully. + */ + bool decodeMemory(const void* buffer, size_t size); + + /** Read in XML from a stream. Returns true if the file can be + read without error. Returns false if an error was encountered. + Error diagnostics are stored in fErrorCode and fLineNumber. + @param stream The stream containg the XML text as UTF-8 characters. + @return true if the XML was parsed successfully. + */ + virtual bool decodeStream(SkStream* stream); + + /** Parse the DOM tree starting at the specified node. Returns true if it can be + parsed without error. Returns false if an error was encountered. + Error diagnostics are stored in fErrorCode and fLineNumber. + @return true if the DOM was parsed successfully. + */ + virtual bool decodeDOM(const SkDOM&, const SkDOMNode*); + + /** Read in XML from a URI. Returns true if the file can be + read without error. Returns false if an error was encountered. + Error diagnostics are stored in fErrorCode and fLineNumber. + @param uri The complete url path to be read (either ftp, http or https). + @return true if the XML was parsed successfully. + */ + bool decodeURI(const char uri[]); + + /** Pass a char event, usually a keyboard symbol, to the animator. + This triggers events of the form + and other mouse events. + @param state The mouse state, described by SkView::Click::State : values are + down == 0, moved == 1, up == 2 + @param x The x-position of the mouse + @param y The y-position of the mouse + @return true if the event was dispatched successfully. + */ + bool doClickEvent(int state, SkScalar x, SkScalar y); + + /** Pass a meta-key event, such as an arrow , to the animator. + This triggers events of the form element that specifies a minimal + redraw area. + */ + DifferenceType draw(SkCanvas* canvas, SkPaint* paint, SkMSec time); + + /** Draws one frame of the animation, using a new Paint each time. + The first call to draw always + draws the initial frame of the animation. Subsequent calls draw + the offset into the animation by + subtracting the initial time from the current time. + @param canvas The canvas to draw into. + @param time The offset into the current animation. + @return kNotDifferent if there are no active animations; kDifferent if there are active animations; and + kPartiallyDifferent if the document contains an active element that specifies a minimal + redraw area. + */ + DifferenceType draw(SkCanvas* canvas, SkMSec time); + + /** Experimental: + Helper to choose whether to return a SkView::Click handler. + @param x ignored + @param y ignored + @return true if a mouseDown event handler is enabled. + */ + bool findClickEvent(SkScalar x, SkScalar y); + + + /** Get the nested animator associated with this element, if any. + Use this to access a movie's event sink, to send events to movies. + @param element the value returned by getElement + @return the internal animator. + */ + const SkAnimator* getAnimator(const SkDisplayable* element) const; + + /** Returns the scalar value of the specified element's attribute[index] + @param element the value returned by getElement + @param field the value returned by getField + @param index the array entry + @return the integer value to retrieve, or SK_NaN32 if unsuccessful + */ + int32_t getArrayInt(const SkDisplayable* element, const SkMemberInfo* field, int index); + + /** Returns the scalar value of the specified element's attribute[index] + @param elementID is the value of the id attribute in the XML of this element + @param fieldName specifies the name of the attribute + @param index the array entry + @return the integer value to retrieve, or SK_NaN32 if unsuccessful + */ + int32_t getArrayInt(const char* elementID, const char* fieldName, int index); + + /** Returns the scalar value of the specified element's attribute[index] + @param element the value returned by getElement + @param field the value returned by getField + @param index the array entry + @return the scalar value to retrieve, or SK_ScalarNaN if unsuccessful + */ + SkScalar getArrayScalar(const SkDisplayable* element, const SkMemberInfo* field, int index); + + /** Returns the scalar value of the specified element's attribute[index] + @param elementID is the value of the id attribute in the XML of this element + @param fieldName specifies the name of the attribute + @param index the array entry + @return the scalar value to retrieve, or SK_ScalarNaN if unsuccessful + */ + SkScalar getArrayScalar(const char* elementID, const char* fieldName, int index); + + /** Returns the string value of the specified element's attribute[index] + @param element is a value returned by getElement + @param field is a value returned by getField + @param index the array entry + @return the string value to retrieve, or null if unsuccessful + */ + const char* getArrayString(const SkDisplayable* element, const SkMemberInfo* field, int index); + + /** Returns the string value of the specified element's attribute[index] + @param elementID is the value of the id attribute in the XML of this element + @param fieldName specifies the name of the attribute + @param index the array entry + @return the string value to retrieve, or null if unsuccessful + */ + const char* getArrayString(const char* elementID, const char* fieldName, int index); + + /** Returns the XML element corresponding to the given ID. + @param elementID is the value of the id attribute in the XML of this element + @return the element matching the ID, or null if the element can't be found + */ + const SkDisplayable* getElement(const char* elementID); + + /** Returns the element type corresponding to the XML element. + The element type matches the element name; for instance, returns kElement_LineType + @param element is a value returned by getElement + @return element type, or 0 if the element can't be found + */ + SkElementType getElementType(const SkDisplayable* element); + + /** Returns the element type corresponding to the given ID. + @param elementID is the value of the id attribute in the XML of this element + @return element type, or 0 if the element can't be found + */ + SkElementType getElementType(const char* elementID); + + /** Returns the XML field of the named attribute in the XML element. + @param element is a value returned by getElement + @param fieldName is the attribute to return + @return the attribute matching the fieldName, or null if the element can't be found + */ + const SkMemberInfo* getField(const SkDisplayable* element, const char* fieldName); + + /** Returns the XML field of the named attribute in the XML element matching the elementID. + @param elementID is the value of the id attribute in the XML of this element + @param fieldName is the attribute to return + @return the attribute matching the fieldName, or null if the element can't be found + */ + const SkMemberInfo* getField(const char* elementID, const char* fieldName); + + /** Returns the value type coresponding to the element's attribute. + The value type matches the XML schema: and may be kField_BooleanType, kField_ScalarType, etc. + @param field is a value returned by getField + @return the attribute type, or 0 if the element can't be found + */ + SkFieldType getFieldType(const SkMemberInfo* field); + + /** Returns the value type coresponding to the element's attribute. + @param elementID is the value of the id attribute in the XML of this element + @param fieldName specifies the name of the attribute + @return the attribute type, or 0 if the element can't be found + */ + SkFieldType getFieldType(const char* elementID, const char* fieldName); + + /** Returns the recommended animation interval. Returns zero if no + interval is specified. + */ + SkMSec getInterval(); + + /** Returns the partial rectangle to invalidate after drawing. Call after draw() returns + kIsPartiallyDifferent to do a mimimal inval(). */ + void getInvalBounds(SkRect* inval); + + /** Returns the details of any error encountered while parsing the XML. + */ + const SkXMLParserError* getParserError(); + + /** Returns the details of any error encountered while parsing the XML as string. + */ + const char* getParserErrorString(); + + /** Returns the scalar value of the specified element's attribute + @param element is a value returned by getElement + @param field is a value returned by getField + @return the integer value to retrieve, or SK_NaN32 if not found + */ + int32_t getInt(const SkDisplayable* element, const SkMemberInfo* field); + + /** Returns the scalar value of the specified element's attribute + @param elementID is the value of the id attribute in the XML of this element + @param fieldName specifies the name of the attribute + @return the integer value to retrieve, or SK_NaN32 if not found + */ + int32_t getInt(const char* elementID, const char* fieldName); + + /** Returns the scalar value of the specified element's attribute + @param element is a value returned by getElement + @param field is a value returned by getField + @return the scalar value to retrieve, or SK_ScalarNaN if not found + */ + SkScalar getScalar(const SkDisplayable* element, const SkMemberInfo* field); + + /** Returns the scalar value of the specified element's attribute + @param elementID is the value of the id attribute in the XML of this element + @param fieldName specifies the name of the attribute + @return the scalar value to retrieve, or SK_ScalarNaN if not found + */ + SkScalar getScalar(const char* elementID, const char* fieldName); + + /** Returns the string value of the specified element's attribute + @param element is a value returned by getElement + @param field is a value returned by getField + @return the string value to retrieve, or null if not found + */ + const char* getString(const SkDisplayable* element, const SkMemberInfo* field); + + /** Returns the string value of the specified element's attribute + @param elementID is the value of the id attribute in the XML of this element + @param fieldName specifies the name of the attribute + @return the string value to retrieve, or null if not found + */ + const char* getString(const char* elementID, const char* fieldName); + + /** Gets the file default directory of the URL base path set explicitly or by reading the last URL. */ + const char* getURIBase(); + + /** Resets the animator to a newly created state with no animation data. */ + void initialize(); + + /** Experimental. Resets any active animations so that the next time passed is treated as + time zero. */ + void reset(); + + /** Sets the scalar value of the specified element's attribute + @param elementID is the value of the id attribute in the XML of this element + @param fieldName specifies the name of the attribute + @param array is the c-style array of integers + @param count is the length of the array + @return true if the value was set successfully + */ + bool setArrayInt(const char* elementID, const char* fieldName, const int* array, int count); + + /** Sets the scalar value of the specified element's attribute + @param elementID is the value of the id attribute in the XML of this element + @param fieldName specifies the name of the attribute + @param array is the c-style array of strings + @param count is the length of the array + @return true if the value was set successfully + */ + bool setArrayString(const char* elementID, const char* fieldName, const char** array, int count); + + /** Sets the scalar value of the specified element's attribute + @param elementID is the value of the id attribute in the XML of this element + @param fieldName specifies the name of the attribute + @param data the integer value to set + @return true if the value was set successfully + */ + bool setInt(const char* elementID, const char* fieldName, int32_t data); + + /** Sets the scalar value of the specified element's attribute + @param elementID is the value of the id attribute in the XML of this element + @param fieldName specifies the name of the attribute + @param data the scalar value to set + @return true if the value was set successfully + */ + bool setScalar(const char* elementID, const char* fieldName, SkScalar data); + + /** Sets the string value of the specified element's attribute + @param elementID is the value of the id attribute in the XML of this element + @param fieldName specifies the name of the attribute + @param data the string value to set + @return true if the value was set successfully + */ + bool setString(const char* elementID, const char* fieldName, const char* data); + + /** Sets the file default directory of the URL base path + @param path the directory path + */ + void setURIBase(const char* path); + + typedef void* Handler; + // This guy needs to be exported to java, so don't make it virtual + void setHostHandler(Handler handler) { + this->onSetHostHandler(handler); + } + + /** \class Timeline + Returns current time to animator. To return a custom timeline, create a child + class and override the getMSecs method. + */ + class Timeline { + public: + virtual ~Timeline() {} + + /** Returns the current time in milliseconds */ + virtual SkMSec getMSecs() const = 0; + }; + + /** Sets a user class to return the current time to the animator. + Optional; if not called, the system clock will be used by calling + SkEvent::GetMSecsSinceStartup instead. + @param callBack the time function + */ + void setTimeline(const Timeline& ); + + static void Init(bool runUnitTests); + static void Term(); + + /** The event sink events generated by the animation are posted to. + Screenplay also posts an inval event to this event sink after processing an + event to force a redraw. + @param target the event sink id + */ + void setHostEventSinkID(SkEventSinkID hostID); + SkEventSinkID getHostEventSinkID() const; + + // helper + void setHostEventSink(SkEventSink* sink) { + this->setHostEventSinkID(sink ? sink->getSinkID() : 0); + } + + virtual void setJavaOwner(Handler owner); + +#ifdef SK_DEBUG + virtual void eventDone(const SkEvent& evt); + virtual bool isTrackingEvents(); + static bool NoLeaks(); +#endif + +protected: + virtual void onSetHostHandler(Handler handler); + virtual void onEventPost(SkEvent*, SkEventSinkID); + virtual void onEventPostTime(SkEvent*, SkEventSinkID, SkMSec time); + +private: +// helper functions for setters + bool setArray(SkDisplayable* element, const SkMemberInfo* field, SkTypedArray array); + bool setArray(const char* elementID, const char* fieldName, SkTypedArray array); + bool setInt(SkDisplayable* element, const SkMemberInfo* field, int32_t data); + bool setScalar(SkDisplayable* element, const SkMemberInfo* field, SkScalar data); + bool setString(SkDisplayable* element, const SkMemberInfo* field, const char* data); + + virtual bool onEvent(const SkEvent&); + SkAnimateMaker* fMaker; + friend class SkAnimateMaker; + friend class SkAnimatorScript; + friend class SkAnimatorScript2; + friend class SkApply; + friend class SkDisplayMovie; + friend class SkDisplayType; + friend class SkPost; + friend class SkXMLAnimatorWriter; +}; + +#endif diff --git a/libskia/include/animator/SkAnimatorView.h b/libskia/include/animator/SkAnimatorView.h new file mode 100644 index 00000000..2b2c61b5 --- /dev/null +++ b/libskia/include/animator/SkAnimatorView.h @@ -0,0 +1,39 @@ + +/* + * Copyright 2006 The Android Open Source Project + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + + +#ifndef SkAnimatorView_DEFINED +#define SkAnimatorView_DEFINED + +#include "SkView.h" +#include "SkAnimator.h" + +class SkAnimatorView : public SkView { +public: + SkAnimatorView(); + virtual ~SkAnimatorView(); + + SkAnimator* getAnimator() const { return fAnimator; } + + bool decodeFile(const char path[]); + bool decodeMemory(const void* buffer, size_t size); + bool decodeStream(SkStream* stream); + +protected: + // overrides + virtual bool onEvent(const SkEvent&); + virtual void onDraw(SkCanvas*); + virtual void onInflate(const SkDOM&, const SkDOM::Node*); + +private: + SkAnimator* fAnimator; + + typedef SkView INHERITED; +}; + +#endif diff --git a/libskia/include/c/sk_canvas.h b/libskia/include/c/sk_canvas.h new file mode 100644 index 00000000..1e1dd24f --- /dev/null +++ b/libskia/include/c/sk_canvas.h @@ -0,0 +1,159 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +// EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL +// DO NOT USE -- FOR INTERNAL TESTING ONLY + +#ifndef sk_canvas_DEFINED +#define sk_canvas_DEFINED + +#include "sk_types.h" + +SK_C_PLUS_PLUS_BEGIN_GUARD + +/** + Save the current matrix and clip on the canvas. When the + balancing call to sk_canvas_restore() is made, the previous matrix + and clip are restored. +*/ +SK_API void sk_canvas_save(sk_canvas_t*); +/** + This behaves the same as sk_canvas_save(), but in addition it + allocates an offscreen surface. All drawing calls are directed + there, and only when the balancing call to sk_canvas_restore() is + made is that offscreen transfered to the canvas (or the previous + layer). + + @param sk_rect_t* (may be null) This rect, if non-null, is used as + a hint to limit the size of the offscreen, and + thus drawing may be clipped to it, though that + clipping is not guaranteed to happen. If exact + clipping is desired, use sk_canvas_clip_rect(). + @param sk_paint_t* (may be null) The paint is copied, and is applied + to the offscreen when sk_canvas_restore() is + called. +*/ +SK_API void sk_canvas_save_layer(sk_canvas_t*, const sk_rect_t*, const sk_paint_t*); +/** + This call balances a previous call to sk_canvas_save() or + sk_canvas_save_layer(), and is used to remove all modifications to + the matrix and clip state since the last save call. It is an + error to call sk_canvas_restore() more times than save and + save_layer were called. +*/ +SK_API void sk_canvas_restore(sk_canvas_t*); + +/** + Preconcat the current coordinate transformation matrix with the + specified translation. +*/ +SK_API void sk_canvas_translate(sk_canvas_t*, float dx, float dy); +/** + Preconcat the current coordinate transformation matrix with the + specified scale. +*/ +SK_API void sk_canvas_scale(sk_canvas_t*, float sx, float sy); +/** + Preconcat the current coordinate transformation matrix with the + specified rotation in degrees. +*/ +SK_API void sk_canvas_rotate_degrees(sk_canvas_t*, float degrees); +/** + Preconcat the current coordinate transformation matrix with the + specified rotation in radians. +*/ +SK_API void sk_canvas_rotate_radians(sk_canvas_t*, float radians); +/** + Preconcat the current coordinate transformation matrix with the + specified skew. +*/ +SK_API void sk_canvas_skew(sk_canvas_t*, float sx, float sy); +/** + Preconcat the current coordinate transformation matrix with the + specified matrix. +*/ +SK_API void sk_canvas_concat(sk_canvas_t*, const sk_matrix_t*); + +/** + Modify the current clip with the specified rectangle. The new + current clip will be the intersection of the old clip and the + rectange. +*/ +SK_API void sk_canvas_clip_rect(sk_canvas_t*, const sk_rect_t*); +/** + Modify the current clip with the specified path. The new + current clip will be the intersection of the old clip and the + path. +*/ +SK_API void sk_canvas_clip_path(sk_canvas_t*, const sk_path_t*); + +/** + Fill the entire canvas (restricted to the current clip) with the + specified paint. +*/ +SK_API void sk_canvas_draw_paint(sk_canvas_t*, const sk_paint_t*); +/** + Draw the specified rectangle using the specified paint. The + rectangle will be filled or stroked based on the style in the + paint. +*/ +SK_API void sk_canvas_draw_rect(sk_canvas_t*, const sk_rect_t*, const sk_paint_t*); +/** + * Draw the circle centered at (cx, cy) with radius rad using the specified paint. + * The circle will be filled or framed based on the style in the paint + */ +SK_API void sk_canvas_draw_circle(sk_canvas_t*, float cx, float cy, float rad, const sk_paint_t*); +/** + Draw the specified oval using the specified paint. The oval will be + filled or framed based on the style in the paint +*/ +SK_API void sk_canvas_draw_oval(sk_canvas_t*, const sk_rect_t*, const sk_paint_t*); +/** + Draw the specified path using the specified paint. The path will be + filled or framed based on the style in the paint +*/ +SK_API void sk_canvas_draw_path(sk_canvas_t*, const sk_path_t*, const sk_paint_t*); +/** + Draw the specified image, with its top/left corner at (x,y), using + the specified paint, transformed by the current matrix. + + @param sk_paint_t* (may be NULL) the paint used to draw the image. +*/ +SK_API void sk_canvas_draw_image(sk_canvas_t*, const sk_image_t*, + float x, float y, const sk_paint_t*); +/** + Draw the specified image, scaling and translating so that it fills + the specified dst rect. If the src rect is non-null, only that + subset of the image is transformed and drawn. + + @param sk_paint_t* (may be NULL) The paint used to draw the image. +*/ +SK_API void sk_canvas_draw_image_rect(sk_canvas_t*, const sk_image_t*, + const sk_rect_t* src, + const sk_rect_t* dst, const sk_paint_t*); + +/** + Draw the picture into this canvas (replay the pciture's drawing commands). + + @param sk_matrix_t* If non-null, apply that matrix to the CTM when + drawing this picture. This is logically + equivalent to: save, concat, draw_picture, + restore. + + @param sk_paint_t* If non-null, draw the picture into a temporary + buffer, and then apply the paint's alpha, + colorfilter, imagefilter, and xfermode to that + buffer as it is drawn to the canvas. This is + logically equivalent to save_layer(paint), + draw_picture, restore. +*/ +SK_API void sk_canvas_draw_picture(sk_canvas_t*, const sk_picture_t*, + const sk_matrix_t*, const sk_paint_t*); + +SK_C_PLUS_PLUS_END_GUARD + +#endif diff --git a/libskia/include/c/sk_data.h b/libskia/include/c/sk_data.h new file mode 100644 index 00000000..90333bba --- /dev/null +++ b/libskia/include/c/sk_data.h @@ -0,0 +1,70 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +// EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL +// DO NOT USE -- FOR INTERNAL TESTING ONLY + +#ifndef sk_data_DEFINED +#define sk_data_DEFINED + +#include "sk_types.h" + +SK_C_PLUS_PLUS_BEGIN_GUARD + +/** + Returns a new empty sk_data_t. This call must be balanced with a call to + sk_data_unref(). +*/ +SK_API sk_data_t* sk_data_new_empty(); +/** + Returns a new sk_data_t by copying the specified source data. + This call must be balanced with a call to sk_data_unref(). +*/ +SK_API sk_data_t* sk_data_new_with_copy(const void* src, size_t length); +/** + Pass ownership of the given memory to a new sk_data_t, which will + call free() when the refernce count of the data goes to zero. For + example: + size_t length = 1024; + void* buffer = malloc(length); + memset(buffer, 'X', length); + sk_data_t* data = sk_data_new_from_malloc(buffer, length); + This call must be balanced with a call to sk_data_unref(). +*/ +SK_API sk_data_t* sk_data_new_from_malloc(const void* memory, size_t length); +/** + Returns a new sk_data_t using a subset of the data in the + specified source sk_data_t. This call must be balanced with a + call to sk_data_unref(). +*/ +SK_API sk_data_t* sk_data_new_subset(const sk_data_t* src, size_t offset, size_t length); + +/** + Increment the reference count on the given sk_data_t. Must be + balanced by a call to sk_data_unref(). +*/ +SK_API void sk_data_ref(const sk_data_t*); +/** + Decrement the reference count. If the reference count is 1 before + the decrement, then release both the memory holding the sk_data_t + and the memory it is managing. New sk_data_t are created with a + reference count of 1. +*/ +SK_API void sk_data_unref(const sk_data_t*); + +/** + Returns the number of bytes stored. +*/ +SK_API size_t sk_data_get_size(const sk_data_t*); +/** + Returns the pointer to the data. + */ +SK_API const void* sk_data_get_data(const sk_data_t*); + +SK_C_PLUS_PLUS_END_GUARD + +#endif diff --git a/libskia/include/c/sk_image.h b/libskia/include/c/sk_image.h new file mode 100644 index 00000000..e90649d7 --- /dev/null +++ b/libskia/include/c/sk_image.h @@ -0,0 +1,71 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +// EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL +// DO NOT USE -- FOR INTERNAL TESTING ONLY + +#ifndef sk_image_DEFINED +#define sk_image_DEFINED + +#include "sk_types.h" + +SK_C_PLUS_PLUS_BEGIN_GUARD + +/** + * Return a new image that has made a copy of the provided pixels, or NULL on failure. + * Balance with a call to sk_image_unref(). + */ +SK_API sk_image_t* sk_image_new_raster_copy(const sk_imageinfo_t*, const void* pixels, size_t rowBytes); + +/** + * If the specified data can be interpreted as a compressed image (e.g. PNG or JPEG) then this + * returns an image. If the encoded data is not supported, returns NULL. + * + * On success, the encoded data may be processed immediately, or it may be ref()'d for later + * use. + */ +SK_API sk_image_t* sk_image_new_from_encoded(const sk_data_t* encoded, const sk_irect_t* subset); + +/** + * Encode the image's pixels and return the result as a new PNG in a + * sk_data_t, which the caller must manage: call sk_data_unref() when + * they are done. + * + * If the image type cannot be encoded, this will return NULL. + */ +SK_API sk_data_t* sk_image_encode(const sk_image_t*); + +/** + * Increment the reference count on the given sk_image_t. Must be + * balanced by a call to sk_image_unref(). +*/ +SK_API void sk_image_ref(const sk_image_t*); +/** + * Decrement the reference count. If the reference count is 1 before + * the decrement, then release both the memory holding the sk_image_t + * and the memory it is managing. New sk_image_t are created with a + reference count of 1. +*/ +SK_API void sk_image_unref(const sk_image_t*); + +/** + * Return the width of the sk_image_t/ + */ +SK_API int sk_image_get_width(const sk_image_t*); +/** + * Return the height of the sk_image_t/ + */ +SK_API int sk_image_get_height(const sk_image_t*); + +/** + * Returns a non-zero value unique among all images. + */ +SK_API uint32_t sk_image_get_unique_id(const sk_image_t*); + +SK_C_PLUS_PLUS_END_GUARD + +#endif diff --git a/libskia/include/c/sk_maskfilter.h b/libskia/include/c/sk_maskfilter.h new file mode 100644 index 00000000..5c22a063 --- /dev/null +++ b/libskia/include/c/sk_maskfilter.h @@ -0,0 +1,47 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +// EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL +// DO NOT USE -- FOR INTERNAL TESTING ONLY + +#ifndef sk_maskfilter_DEFINED +#define sk_maskfilter_DEFINED + +#include "sk_types.h" + +typedef enum { + NORMAL_SK_BLUR_STYLE, //!< fuzzy inside and outside + SOLID_SK_BLUR_STYLE, //!< solid inside, fuzzy outside + OUTER_SK_BLUR_STYLE, //!< nothing inside, fuzzy outside + INNER_SK_BLUR_STYLE, //!< fuzzy inside, nothing outside +} sk_blurstyle_t; + +SK_C_PLUS_PLUS_BEGIN_GUARD + +/** + Increment the reference count on the given sk_maskfilter_t. Must be + balanced by a call to sk_maskfilter_unref(). +*/ +void sk_maskfilter_ref(sk_maskfilter_t*); +/** + Decrement the reference count. If the reference count is 1 before + the decrement, then release both the memory holding the + sk_maskfilter_t and any other associated resources. New + sk_maskfilter_t are created with a reference count of 1. +*/ +void sk_maskfilter_unref(sk_maskfilter_t*); + +/** + Create a blur maskfilter. + @param sk_blurstyle_t The SkBlurStyle to use + @param sigma Standard deviation of the Gaussian blur to apply. Must be > 0. +*/ +sk_maskfilter_t* sk_maskfilter_new_blur(sk_blurstyle_t, float sigma); + +SK_C_PLUS_PLUS_END_GUARD + +#endif diff --git a/libskia/include/c/sk_matrix.h b/libskia/include/c/sk_matrix.h new file mode 100644 index 00000000..83f0122b --- /dev/null +++ b/libskia/include/c/sk_matrix.h @@ -0,0 +1,49 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +// EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL +// DO NOT USE -- FOR INTERNAL TESTING ONLY + +#ifndef sk_matrix_DEFINED +#define sk_matrix_DEFINED + +#include "sk_types.h" + +SK_C_PLUS_PLUS_BEGIN_GUARD + +/** Set the matrix to identity */ +void sk_matrix_set_identity(sk_matrix_t*); + +/** Set the matrix to translate by (tx, ty). */ +void sk_matrix_set_translate(sk_matrix_t*, float tx, float ty); +/** + Preconcats the matrix with the specified translation. + M' = M * T(dx, dy) +*/ +void sk_matrix_pre_translate(sk_matrix_t*, float tx, float ty); +/** + Postconcats the matrix with the specified translation. + M' = T(dx, dy) * M +*/ +void sk_matrix_post_translate(sk_matrix_t*, float tx, float ty); + +/** Set the matrix to scale by sx and sy. */ +void sk_matrix_set_scale(sk_matrix_t*, float sx, float sy); +/** + Preconcats the matrix with the specified scale. + M' = M * S(sx, sy) +*/ +void sk_matrix_pre_scale(sk_matrix_t*, float sx, float sy); +/** + Postconcats the matrix with the specified scale. + M' = S(sx, sy) * M +*/ +void sk_matrix_post_scale(sk_matrix_t*, float sx, float sy); + +SK_C_PLUS_PLUS_END_GUARD + +#endif diff --git a/libskia/include/c/sk_paint.h b/libskia/include/c/sk_paint.h new file mode 100644 index 00000000..e0886ad3 --- /dev/null +++ b/libskia/include/c/sk_paint.h @@ -0,0 +1,145 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +// EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL +// DO NOT USE -- FOR INTERNAL TESTING ONLY + +#ifndef sk_paint_DEFINED +#define sk_paint_DEFINED + +#include "sk_types.h" + +SK_C_PLUS_PLUS_BEGIN_GUARD + +/** + Create a new paint with default settings: + antialias : false + stroke : false + stroke width : 0.0f (hairline) + stroke miter : 4.0f + stroke cap : BUTT_SK_STROKE_CAP + stroke join : MITER_SK_STROKE_JOIN + color : opaque black + shader : NULL + maskfilter : NULL + xfermode_mode : SRCOVER_SK_XFERMODE_MODE +*/ +SK_API sk_paint_t* sk_paint_new(); +/** + Release the memory storing the sk_paint_t and unref() all + associated objects. +*/ +SK_API void sk_paint_delete(sk_paint_t*); + +/** + Return true iff the paint has antialiasing enabled. +*/ +SK_API bool sk_paint_is_antialias(const sk_paint_t*); +/** + Set to true to enable antialiasing, false to disable it on this + sk_paint_t. +*/ +SK_API void sk_paint_set_antialias(sk_paint_t*, bool); + +/** + Return the paint's curent drawing color. +*/ +SK_API sk_color_t sk_paint_get_color(const sk_paint_t*); +/** + Set the paint's curent drawing color. +*/ +SK_API void sk_paint_set_color(sk_paint_t*, sk_color_t); + +/* stroke settings */ + +/** + Return true iff stroking is enabled rather than filling on this + sk_paint_t. +*/ +SK_API bool sk_paint_is_stroke(const sk_paint_t*); +/** + Set to true to enable stroking rather than filling with this + sk_paint_t. +*/ +SK_API void sk_paint_set_stroke(sk_paint_t*, bool); + +/** + Return the width for stroking. A value of 0 strokes in hairline mode. + */ +SK_API float sk_paint_get_stroke_width(const sk_paint_t*); +/** + Set the width for stroking. A value of 0 strokes in hairline mode + (always draw 1-pixel wide, regardless of the matrix). + */ +SK_API void sk_paint_set_stroke_width(sk_paint_t*, float width); + +/** + Return the paint's stroke miter value. This is used to control the + behavior of miter joins when the joins angle is sharp. +*/ +SK_API float sk_paint_get_stroke_miter(const sk_paint_t*); +/** + Set the paint's stroke miter value. This is used to control the + behavior of miter joins when the joins angle is sharp. This value + must be >= 0. +*/ +SK_API void sk_paint_set_stroke_miter(sk_paint_t*, float miter); + +typedef enum { + BUTT_SK_STROKE_CAP, + ROUND_SK_STROKE_CAP, + SQUARE_SK_STROKE_CAP +} sk_stroke_cap_t; + +/** + Return the paint's stroke cap type, controlling how the start and + end of stroked lines and paths are treated. +*/ +SK_API sk_stroke_cap_t sk_paint_get_stroke_cap(const sk_paint_t*); +/** + Set the paint's stroke cap type, controlling how the start and + end of stroked lines and paths are treated. +*/ +SK_API void sk_paint_set_stroke_cap(sk_paint_t*, sk_stroke_cap_t); + +typedef enum { + MITER_SK_STROKE_JOIN, + ROUND_SK_STROKE_JOIN, + BEVEL_SK_STROKE_JOIN +} sk_stroke_join_t; + +/** + Return the paint's stroke join type, specifies the treatment that + is applied to corners in paths and rectangles + */ +SK_API sk_stroke_join_t sk_paint_get_stroke_join(const sk_paint_t*); +/** + Set the paint's stroke join type, specifies the treatment that + is applied to corners in paths and rectangles + */ +SK_API void sk_paint_set_stroke_join(sk_paint_t*, sk_stroke_join_t); + +/** + * Set the paint's shader to the specified parameter. This will automatically call unref() on + * any previous value, and call ref() on the new value. + */ +SK_API void sk_paint_set_shader(sk_paint_t*, sk_shader_t*); + +/** + * Set the paint's maskfilter to the specified parameter. This will automatically call unref() on + * any previous value, and call ref() on the new value. + */ +SK_API void sk_paint_set_maskfilter(sk_paint_t*, sk_maskfilter_t*); + +/** + * Set the paint's xfermode to the specified parameter. + */ +SK_API void sk_paint_set_xfermode_mode(sk_paint_t*, sk_xfermode_mode_t); + +SK_C_PLUS_PLUS_END_GUARD + +#endif diff --git a/libskia/include/c/sk_path.h b/libskia/include/c/sk_path.h new file mode 100644 index 00000000..6b4e83d3 --- /dev/null +++ b/libskia/include/c/sk_path.h @@ -0,0 +1,84 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +// EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL +// DO NOT USE -- FOR INTERNAL TESTING ONLY + +#ifndef sk_path_DEFINED +#define sk_path_DEFINED + +#include "sk_types.h" + +SK_C_PLUS_PLUS_BEGIN_GUARD + +typedef enum { + CW_SK_PATH_DIRECTION, + CCW_SK_PATH_DIRECTION, +} sk_path_direction_t; + +/** Create a new, empty path. */ +SK_API sk_path_t* sk_path_new(); +/** Release the memory used by a sk_path_t. */ +SK_API void sk_path_delete(sk_path_t*); + +/** Set the beginning of the next contour to the point (x,y). */ +SK_API void sk_path_move_to(sk_path_t*, float x, float y); +/** + Add a line from the last point to the specified point (x,y). If no + sk_path_move_to() call has been made for this contour, the first + point is automatically set to (0,0). +*/ +SK_API void sk_path_line_to(sk_path_t*, float x, float y); +/** + Add a quadratic bezier from the last point, approaching control + point (x0,y0), and ending at (x1,y1). If no sk_path_move_to() call + has been made for this contour, the first point is automatically + set to (0,0). +*/ +SK_API void sk_path_quad_to(sk_path_t*, float x0, float y0, float x1, float y1); +/** + Add a conic curve from the last point, approaching control point + (x0,y01), and ending at (x1,y1) with weight w. If no + sk_path_move_to() call has been made for this contour, the first + point is automatically set to (0,0). +*/ +SK_API void sk_path_conic_to(sk_path_t*, float x0, float y0, float x1, float y1, float w); +/** + Add a cubic bezier from the last point, approaching control points + (x0,y0) and (x1,y1), and ending at (x2,y2). If no + sk_path_move_to() call has been made for this contour, the first + point is automatically set to (0,0). +*/ +SK_API void sk_path_cubic_to(sk_path_t*, + float x0, float y0, + float x1, float y1, + float x2, float y2); +/** + Close the current contour. If the current point is not equal to the + first point of the contour, a line segment is automatically added. +*/ +SK_API void sk_path_close(sk_path_t*); + +/** + Add a closed rectangle contour to the path. +*/ +SK_API void sk_path_add_rect(sk_path_t*, const sk_rect_t*, sk_path_direction_t); +/** + Add a closed oval contour to the path +*/ +SK_API void sk_path_add_oval(sk_path_t*, const sk_rect_t*, sk_path_direction_t); + +/** + * If the path is empty, return false and set the rect parameter to [0, 0, 0, 0]. + * else return true and set the rect parameter to the bounds of the control-points + * of the path. + */ +SK_API bool sk_path_get_bounds(const sk_path_t*, sk_rect_t*); + +SK_C_PLUS_PLUS_END_GUARD + +#endif diff --git a/libskia/include/c/sk_picture.h b/libskia/include/c/sk_picture.h new file mode 100644 index 00000000..338b7d90 --- /dev/null +++ b/libskia/include/c/sk_picture.h @@ -0,0 +1,70 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +// EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL +// DO NOT USE -- FOR INTERNAL TESTING ONLY + +#ifndef sk_picture_DEFINED +#define sk_picture_DEFINED + +#include "sk_types.h" + +SK_C_PLUS_PLUS_BEGIN_GUARD + +/** + Create a new sk_picture_recorder_t. Its resources should be + released with a call to sk_picture_recorder_delete(). +*/ +sk_picture_recorder_t* sk_picture_recorder_new(); +/** + Release the memory and other resources used by this + sk_picture_recorder_t. +*/ +void sk_picture_recorder_delete(sk_picture_recorder_t*); + +/** + Returns the canvas that records the drawing commands + + @param sk_rect_t* the cull rect used when recording this + picture. Any drawing the falls outside of this + rect is undefined, and may be drawn or it may not. +*/ +sk_canvas_t* sk_picture_recorder_begin_recording(sk_picture_recorder_t*, const sk_rect_t*); +/** + Signal that the caller is done recording. This invalidates the + canvas returned by begin_recording. Ownership of the sk_picture_t + is passed to the caller, who must call sk_picture_unref() when + they are done using it. The returned picture is immutable. +*/ +sk_picture_t* sk_picture_recorder_end_recording(sk_picture_recorder_t*); + +/** + Increment the reference count on the given sk_picture_t. Must be + balanced by a call to sk_picture_unref(). +*/ +void sk_picture_ref(sk_picture_t*); +/** + Decrement the reference count. If the reference count is 1 before + the decrement, then release both the memory holding the + sk_picture_t and any resouces it may be managing. New + sk_picture_t are created with a reference count of 1. +*/ +void sk_picture_unref(sk_picture_t*); + +/** + Returns a non-zero value unique among all pictures. + */ +uint32_t sk_picture_get_unique_id(sk_picture_t*); + +/** + Return the cull rect specified when this picture was recorded. +*/ +sk_rect_t sk_picture_get_bounds(sk_picture_t*); + +SK_C_PLUS_PLUS_END_GUARD + +#endif diff --git a/libskia/include/c/sk_shader.h b/libskia/include/c/sk_shader.h new file mode 100644 index 00000000..702cda7f --- /dev/null +++ b/libskia/include/c/sk_shader.h @@ -0,0 +1,143 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +// EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL +// DO NOT USE -- FOR INTERNAL TESTING ONLY + +#ifndef sk_shader_DEFINED +#define sk_shader_DEFINED + +#include "sk_types.h" + +SK_C_PLUS_PLUS_BEGIN_GUARD + +void sk_shader_ref(sk_shader_t*); +void sk_shader_unref(sk_shader_t*); + +typedef enum { + CLAMP_SK_SHADER_TILEMODE, + REPEAT_SK_SHADER_TILEMODE, + MIRROR_SK_SHADER_TILEMODE, +} sk_shader_tilemode_t; + +/** + Returns a shader that generates a linear gradient between the two + specified points. + + @param points The start and end points for the gradient. + @param colors The array[count] of colors, to be distributed between + the two points + @param colorPos May be NULL. array[count] of SkScalars, or NULL, of + the relative position of each corresponding color + in the colors array. If this is NULL, the the + colors are distributed evenly between the start + and end point. If this is not null, the values + must begin with 0, end with 1.0, and intermediate + values must be strictly increasing. + @param colorCount Must be >=2. The number of colors (and pos if not + NULL) entries. + @param mode The tiling mode +*/ +sk_shader_t* sk_shader_new_linear_gradient(const sk_point_t points[2], + const sk_color_t colors[], + const float colorPos[], + int colorCount, + sk_shader_tilemode_t tileMode, + const sk_matrix_t* localMatrix); + + +/** + Returns a shader that generates a radial gradient given the center + and radius. + + @param center The center of the circle for this gradient + @param radius Must be positive. The radius of the circle for this + gradient + @param colors The array[count] of colors, to be distributed + between the center and edge of the circle + @param colorPos May be NULL. The array[count] of the relative + position of each corresponding color in the colors + array. If this is NULL, the the colors are + distributed evenly between the center and edge of + the circle. If this is not null, the values must + begin with 0, end with 1.0, and intermediate + values must be strictly increasing. + @param count Must be >= 2. The number of colors (and pos if not + NULL) entries + @param tileMode The tiling mode + @param localMatrix May be NULL +*/ +sk_shader_t* sk_shader_new_radial_gradient(const sk_point_t* center, + float radius, + const sk_color_t colors[], + const float colorPos[], + int colorCount, + sk_shader_tilemode_t tileMode, + const sk_matrix_t* localMatrix); + +/** + Returns a shader that generates a sweep gradient given a center. + + @param center The coordinates of the center of the sweep + @param colors The array[count] of colors, to be distributed around + the center. + @param colorPos May be NULL. The array[count] of the relative + position of each corresponding color in the colors + array. If this is NULL, the the colors are + distributed evenly between the center and edge of + the circle. If this is not null, the values must + begin with 0, end with 1.0, and intermediate + values must be strictly increasing. + @param colorCount Must be >= 2. The number of colors (and pos if + not NULL) entries + @param localMatrix May be NULL +*/ +sk_shader_t* sk_shader_new_sweep_gradient(const sk_point_t* center, + const sk_color_t colors[], + const float colorPos[], + int colorCount, + const sk_matrix_t* localMatrix); + +/** + Returns a shader that generates a conical gradient given two circles, or + returns NULL if the inputs are invalid. The gradient interprets the + two circles according to the following HTML spec. + http://dev.w3.org/html5/2dcontext/#dom-context-2d-createradialgradient + + Returns a shader that generates a sweep gradient given a center. + + @param start, startRadius Defines the first circle. + @param end, endRadius Defines the first circle. + @param colors The array[count] of colors, to be distributed between + the two circles. + @param colorPos May be NULL. The array[count] of the relative + position of each corresponding color in the colors + array. If this is NULL, the the colors are + distributed evenly between the two circles. If + this is not null, the values must begin with 0, + end with 1.0, and intermediate values must be + strictly increasing. + @param colorCount Must be >= 2. The number of colors (and pos if + not NULL) entries + @param tileMode The tiling mode + @param localMatrix May be NULL + +*/ +sk_shader_t* sk_shader_new_two_point_conical_gradient( + const sk_point_t* start, + float startRadius, + const sk_point_t* end, + float endRadius, + const sk_color_t colors[], + const float colorPos[], + int colorCount, + sk_shader_tilemode_t tileMode, + const sk_matrix_t* localMatrix); + +SK_C_PLUS_PLUS_END_GUARD + +#endif diff --git a/libskia/include/c/sk_surface.h b/libskia/include/c/sk_surface.h new file mode 100644 index 00000000..d634185e --- /dev/null +++ b/libskia/include/c/sk_surface.h @@ -0,0 +1,73 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +// EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL +// DO NOT USE -- FOR INTERNAL TESTING ONLY + +#ifndef sk_surface_DEFINED +#define sk_surface_DEFINED + +#include "sk_types.h" + +SK_C_PLUS_PLUS_BEGIN_GUARD + +/** + Return a new surface, with the memory for the pixels automatically + allocated. If the requested surface cannot be created, or the + request is not a supported configuration, NULL will be returned. + + @param sk_imageinfo_t* Specify the width, height, color type, and + alpha type for the surface. + + @param sk_surfaceprops_t* If not NULL, specify additional non-default + properties of the surface. +*/ +SK_API sk_surface_t* sk_surface_new_raster(const sk_imageinfo_t*, const sk_surfaceprops_t*); + +/** + Create a new surface which will draw into the specified pixels + with the specified rowbytes. If the requested surface cannot be + created, or the request is not a supported configuration, NULL + will be returned. + + @param sk_imageinfo_t* Specify the width, height, color type, and + alpha type for the surface. + @param void* pixels Specify the location in memory where the + destination pixels are. This memory must + outlast this surface. + @param size_t rowBytes Specify the difference, in bytes, between + each adjacent row. Should be at least + (width * sizeof(one pixel)). + @param sk_surfaceprops_t* If not NULL, specify additional non-default + properties of the surface. +*/ +SK_API sk_surface_t* sk_surface_new_raster_direct(const sk_imageinfo_t*, + void* pixels, size_t rowBytes, + const sk_surfaceprops_t* props); + +/** + Decrement the reference count. If the reference count is 1 before + the decrement, then release both the memory holding the + sk_surface_t and any pixel memory it may be managing. New + sk_surface_t are created with a reference count of 1. +*/ +SK_API void sk_surface_unref(sk_surface_t*); + +/** + * Return the canvas associated with this surface. Note: the canvas is owned by the surface, + * so the returned object is only valid while the owning surface is valid. + */ +SK_API sk_canvas_t* sk_surface_get_canvas(sk_surface_t*); + +/** + * Call sk_image_unref() when the returned image is no longer used. + */ +SK_API sk_image_t* sk_surface_new_image_snapshot(sk_surface_t*); + +SK_C_PLUS_PLUS_END_GUARD + +#endif diff --git a/libskia/include/c/sk_types.h b/libskia/include/c/sk_types.h new file mode 100644 index 00000000..baa3ac9c --- /dev/null +++ b/libskia/include/c/sk_types.h @@ -0,0 +1,217 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +// EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL +// DO NOT USE -- FOR INTERNAL TESTING ONLY + +#ifndef sk_types_DEFINED +#define sk_types_DEFINED + +#include +#include + +#ifdef __cplusplus + #define SK_C_PLUS_PLUS_BEGIN_GUARD extern "C" { + #define SK_C_PLUS_PLUS_END_GUARD } +#else + #include + #define SK_C_PLUS_PLUS_BEGIN_GUARD + #define SK_C_PLUS_PLUS_END_GUARD +#endif + +#if !defined(SK_API) + #if defined(SKIA_DLL) + #if defined(_MSC_VER) + #if SKIA_IMPLEMENTATION + #define SK_API __declspec(dllexport) + #else + #define SK_API __declspec(dllimport) + #endif + #else + #define SK_API __attribute__((visibility("default"))) + #endif + #else + #define SK_API + #endif +#endif + +/////////////////////////////////////////////////////////////////////////////////////// + +SK_C_PLUS_PLUS_BEGIN_GUARD + +typedef uint32_t sk_color_t; + +/* This macro assumes all arguments are >=0 and <=255. */ +#define sk_color_set_argb(a, r, g, b) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b)) +#define sk_color_get_a(c) (((c) >> 24) & 0xFF) +#define sk_color_get_r(c) (((c) >> 16) & 0xFF) +#define sk_color_get_g(c) (((c) >> 8) & 0xFF) +#define sk_color_get_b(c) (((c) >> 0) & 0xFF) + +typedef enum { + UNKNOWN_SK_COLORTYPE, + RGBA_8888_SK_COLORTYPE, + BGRA_8888_SK_COLORTYPE, + ALPHA_8_SK_COLORTYPE, +} sk_colortype_t; + +typedef enum { + OPAQUE_SK_ALPHATYPE, + PREMUL_SK_ALPHATYPE, + UNPREMUL_SK_ALPHATYPE, +} sk_alphatype_t; + +typedef enum { + INTERSECT_SK_CLIPTYPE, + DIFFERENCE_SK_CLIPTYPE, +} sk_cliptype_t; + +typedef enum { + UNKNOWN_SK_PIXELGEOMETRY, + RGB_H_SK_PIXELGEOMETRY, + BGR_H_SK_PIXELGEOMETRY, + RGB_V_SK_PIXELGEOMETRY, + BGR_V_SK_PIXELGEOMETRY, +} sk_pixelgeometry_t; + +/** + Return the default sk_colortype_t; this is operating-system dependent. +*/ +SK_API sk_colortype_t sk_colortype_get_default_8888(); + +typedef struct { + int32_t width; + int32_t height; + sk_colortype_t colorType; + sk_alphatype_t alphaType; +} sk_imageinfo_t; + +typedef struct { + sk_pixelgeometry_t pixelGeometry; +} sk_surfaceprops_t; + +typedef struct { + float x; + float y; +} sk_point_t; + +typedef struct { + int32_t left; + int32_t top; + int32_t right; + int32_t bottom; +} sk_irect_t; + +typedef struct { + float left; + float top; + float right; + float bottom; +} sk_rect_t; + +typedef struct { + float mat[9]; +} sk_matrix_t; + +/** + A sk_canvas_t encapsulates all of the state about drawing into a + destination This includes a reference to the destination itself, + and a stack of matrix/clip values. +*/ +typedef struct sk_canvas_t sk_canvas_t; +/** + A sk_data_ holds an immutable data buffer. +*/ +typedef struct sk_data_t sk_data_t; +/** + A sk_image_t is an abstraction for drawing a rectagle of pixels. + The content of the image is always immutable, though the actual + storage may change, if for example that image can be re-created via + encoded data or other means. +*/ +typedef struct sk_image_t sk_image_t; +/** + A sk_maskfilter_t is an object that perform transformations on an + alpha-channel mask before drawing it; it may be installed into a + sk_paint_t. Each time a primitive is drawn, it is first + scan-converted into a alpha mask, which os handed to the + maskfilter, which may create a new mask is to render into the + destination. + */ +typedef struct sk_maskfilter_t sk_maskfilter_t; +/** + A sk_paint_t holds the style and color information about how to + draw geometries, text and bitmaps. +*/ +typedef struct sk_paint_t sk_paint_t; +/** + A sk_path_t encapsulates compound (multiple contour) geometric + paths consisting of straight line segments, quadratic curves, and + cubic curves. +*/ +typedef struct sk_path_t sk_path_t; +/** + A sk_picture_t holds recorded canvas drawing commands to be played + back at a later time. +*/ +typedef struct sk_picture_t sk_picture_t; +/** + A sk_picture_recorder_t holds a sk_canvas_t that records commands + to create a sk_picture_t. +*/ +typedef struct sk_picture_recorder_t sk_picture_recorder_t; +/** + A sk_shader_t specifies the source color(s) for what is being drawn. If a + paint has no shader, then the paint's color is used. If the paint + has a shader, then the shader's color(s) are use instead, but they + are modulated by the paint's alpha. +*/ +typedef struct sk_shader_t sk_shader_t; +/** + A sk_surface_t holds the destination for drawing to a canvas. For + raster drawing, the destination is an array of pixels in memory. + For GPU drawing, the destination is a texture or a framebuffer. +*/ +typedef struct sk_surface_t sk_surface_t; + +typedef enum { + CLEAR_SK_XFERMODE_MODE, + SRC_SK_XFERMODE_MODE, + DST_SK_XFERMODE_MODE, + SRCOVER_SK_XFERMODE_MODE, + DSTOVER_SK_XFERMODE_MODE, + SRCIN_SK_XFERMODE_MODE, + DSTIN_SK_XFERMODE_MODE, + SRCOUT_SK_XFERMODE_MODE, + DSTOUT_SK_XFERMODE_MODE, + SRCATOP_SK_XFERMODE_MODE, + DSTATOP_SK_XFERMODE_MODE, + XOR_SK_XFERMODE_MODE, + PLUS_SK_XFERMODE_MODE, + MODULATE_SK_XFERMODE_MODE, + SCREEN_SK_XFERMODE_MODE, + OVERLAY_SK_XFERMODE_MODE, + DARKEN_SK_XFERMODE_MODE, + LIGHTEN_SK_XFERMODE_MODE, + COLORDODGE_SK_XFERMODE_MODE, + COLORBURN_SK_XFERMODE_MODE, + HARDLIGHT_SK_XFERMODE_MODE, + SOFTLIGHT_SK_XFERMODE_MODE, + DIFFERENCE_SK_XFERMODE_MODE, + EXCLUSION_SK_XFERMODE_MODE, + MULTIPLY_SK_XFERMODE_MODE, + HUE_SK_XFERMODE_MODE, + SATURATION_SK_XFERMODE_MODE, + COLOR_SK_XFERMODE_MODE, + LUMINOSITY_SK_XFERMODE_MODE, +} sk_xfermode_mode_t; + +////////////////////////////////////////////////////////////////////////////////////////// + +SK_C_PLUS_PLUS_END_GUARD + +#endif diff --git a/libskia/include/codec/SkAndroidCodec.h b/libskia/include/codec/SkAndroidCodec.h new file mode 100644 index 00000000..a4f46f93 --- /dev/null +++ b/libskia/include/codec/SkAndroidCodec.h @@ -0,0 +1,265 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkAndroidCodec_DEFINED +#define SkAndroidCodec_DEFINED + +#include "SkCodec.h" +#include "SkEncodedImageFormat.h" +#include "SkStream.h" +#include "SkTypes.h" + +/** + * Abstract interface defining image codec functionality that is necessary for + * Android. + */ +class SkAndroidCodec : SkNoncopyable { +public: + /** + * If this stream represents an encoded image that we know how to decode, + * return an SkAndroidCodec that can decode it. Otherwise return NULL. + * + * The SkPngChunkReader handles unknown chunks in PNGs. + * See SkCodec.h for more details. + * + * If NULL is returned, the stream is deleted immediately. Otherwise, the + * SkCodec takes ownership of it, and will delete it when done with it. + */ + static SkAndroidCodec* NewFromStream(SkStream*, SkPngChunkReader* = NULL); + + /** + * If this data represents an encoded image that we know how to decode, + * return an SkAndroidCodec that can decode it. Otherwise return NULL. + * + * The SkPngChunkReader handles unknown chunks in PNGs. + * See SkCodec.h for more details. + */ + static SkAndroidCodec* NewFromData(sk_sp, SkPngChunkReader* = NULL); + static SkAndroidCodec* NewFromData(SkData* data, SkPngChunkReader* reader) { + return NewFromData(sk_ref_sp(data), reader); + } + + virtual ~SkAndroidCodec() {} + + + const SkImageInfo& getInfo() const { return fInfo; } + + /** + * Format of the encoded data. + */ + SkEncodedImageFormat getEncodedFormat() const { return fCodec->getEncodedFormat(); } + + /** + * @param requestedColorType Color type requested by the client + * + * If it is possible to decode to requestedColorType, this returns + * requestedColorType. Otherwise, this returns whichever color type + * is suggested by the codec as the best match for the encoded data. + */ + SkColorType computeOutputColorType(SkColorType requestedColorType); + + /** + * @param requestedUnpremul Indicates if the client requested + * unpremultiplied output + * + * Returns the appropriate alpha type to decode to. If the image + * has alpha, the value of requestedUnpremul will be honored. + */ + SkAlphaType computeOutputAlphaType(bool requestedUnpremul); + + /** + * Returns the dimensions of the scaled output image, for an input + * sampleSize. + * + * When the sample size divides evenly into the original dimensions, the + * scaled output dimensions will simply be equal to the original + * dimensions divided by the sample size. + * + * When the sample size does not divide even into the original + * dimensions, the codec may round up or down, depending on what is most + * efficient to decode. + * + * Finally, the codec will always recommend a non-zero output, so the output + * dimension will always be one if the sampleSize is greater than the + * original dimension. + */ + SkISize getSampledDimensions(int sampleSize) const; + + /** + * Return (via desiredSubset) a subset which can decoded from this codec, + * or false if the input subset is invalid. + * + * @param desiredSubset in/out parameter + * As input, a desired subset of the original bounds + * (as specified by getInfo). + * As output, if true is returned, desiredSubset may + * have been modified to a subset which is + * supported. Although a particular change may have + * been made to desiredSubset to create something + * supported, it is possible other changes could + * result in a valid subset. If false is returned, + * desiredSubset's value is undefined. + * @return true If the input desiredSubset is valid. + * desiredSubset may be modified to a subset + * supported by the codec. + * false If desiredSubset is invalid (NULL or not fully + * contained within the image). + */ + bool getSupportedSubset(SkIRect* desiredSubset) const; + // TODO: Rename SkCodec::getValidSubset() to getSupportedSubset() + + /** + * Returns the dimensions of the scaled, partial output image, for an + * input sampleSize and subset. + * + * @param sampleSize Factor to scale down by. + * @param subset Must be a valid subset of the original image + * dimensions and a subset supported by SkAndroidCodec. + * getSubset() can be used to obtain a subset supported + * by SkAndroidCodec. + * @return Size of the scaled partial image. Or zero size + * if either of the inputs is invalid. + */ + SkISize getSampledSubsetDimensions(int sampleSize, const SkIRect& subset) const; + + /** + * Additional options to pass to getAndroidPixels(). + */ + // FIXME: It's a bit redundant to name these AndroidOptions when this class is already + // called SkAndroidCodec. On the other hand, it's may be a bit confusing to call + // these Options when SkCodec has a slightly different set of Options. Maybe these + // should be DecodeOptions or SamplingOptions? + struct AndroidOptions { + AndroidOptions() + : fZeroInitialized(SkCodec::kNo_ZeroInitialized) + , fSubset(nullptr) + , fColorPtr(nullptr) + , fColorCount(nullptr) + , fSampleSize(1) + {} + + /** + * Indicates is destination pixel memory is zero initialized. + * + * The default is SkCodec::kNo_ZeroInitialized. + */ + SkCodec::ZeroInitialized fZeroInitialized; + + /** + * If not NULL, represents a subset of the original image to decode. + * + * Must be within the bounds returned by getInfo(). + * + * If the EncodedFormat is SkEncodedImageFormat::kWEBP, the top and left + * values must be even. + * + * The default is NULL, meaning a decode of the entire image. + */ + SkIRect* fSubset; + + /** + * If the client has requested a decode to kIndex8_SkColorType + * (specified in the SkImageInfo), then the caller must provide + * storage for up to 256 SkPMColor values in fColorPtr. On success, + * the codec must copy N colors into that storage, (where N is the + * logical number of table entries) and set fColorCount to N. + * + * If the client does not request kIndex8_SkColorType, then the last + * two parameters may be NULL. If fColorCount is not null, it will be + * set to 0. + * + * The default is NULL for both pointers. + */ + SkPMColor* fColorPtr; + int* fColorCount; + + /** + * The client may provide an integer downscale factor for the decode. + * The codec may implement this downscaling by sampling or another + * method if it is more efficient. + * + * The default is 1, representing no downscaling. + */ + int fSampleSize; + }; + + /** + * Decode into the given pixels, a block of memory of size at + * least (info.fHeight - 1) * rowBytes + (info.fWidth * + * bytesPerPixel) + * + * Repeated calls to this function should give the same results, + * allowing the PixelRef to be immutable. + * + * @param info A description of the format (config, size) + * expected by the caller. This can simply be identical + * to the info returned by getInfo(). + * + * This contract also allows the caller to specify + * different output-configs, which the implementation can + * decide to support or not. + * + * A size that does not match getInfo() implies a request + * to scale or subset. If the codec cannot perform this + * scaling or subsetting, it will return an error code. + * + * If info is kIndex8_SkColorType, then the caller must provide storage for up to 256 + * SkPMColor values in options->fColorPtr. On success the codec must copy N colors into + * that storage, (where N is the logical number of table entries) and set + * options->fColorCount to N. + * + * If info is not kIndex8_SkColorType, options->fColorPtr and options->fColorCount may + * be nullptr. + * + * The AndroidOptions object is also used to specify any requested scaling or subsetting + * using options->fSampleSize and options->fSubset. If NULL, the defaults (as specified above + * for AndroidOptions) are used. + * + * @return Result kSuccess, or another value explaining the type of failure. + */ + // FIXME: It's a bit redundant to name this getAndroidPixels() when this class is already + // called SkAndroidCodec. On the other hand, it's may be a bit confusing to call + // this getPixels() when it is a slightly different API than SkCodec's getPixels(). + // Maybe this should be decode() or decodeSubset()? + SkCodec::Result getAndroidPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, + const AndroidOptions* options); + + /** + * Simplified version of getAndroidPixels() where we supply the default AndroidOptions as + * specified above for AndroidOptions. + * + * This will return an error if the info is kIndex_8_SkColorType and also will not perform + * any scaling or subsetting. + */ + SkCodec::Result getAndroidPixels(const SkImageInfo& info, void* pixels, size_t rowBytes); + + SkCodec::Result getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes) { + return this->getAndroidPixels(info, pixels, rowBytes); + } + +protected: + + SkAndroidCodec(SkCodec*); + + SkCodec* codec() const { return fCodec.get(); } + + virtual SkISize onGetSampledDimensions(int sampleSize) const = 0; + + virtual bool onGetSupportedSubset(SkIRect* desiredSubset) const = 0; + + virtual SkCodec::Result onGetAndroidPixels(const SkImageInfo& info, void* pixels, + size_t rowBytes, const AndroidOptions& options) = 0; + +private: + + // This will always be a reference to the info that is contained by the + // embedded SkCodec. + const SkImageInfo& fInfo; + + std::unique_ptr fCodec; +}; +#endif // SkAndroidCodec_DEFINED diff --git a/libskia/include/codec/SkCodec.h b/libskia/include/codec/SkCodec.h new file mode 100644 index 00000000..ebc2b9ab --- /dev/null +++ b/libskia/include/codec/SkCodec.h @@ -0,0 +1,868 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkCodec_DEFINED +#define SkCodec_DEFINED + +#include "../private/SkTemplates.h" +#include "SkColor.h" +#include "SkEncodedImageFormat.h" +#include "SkEncodedInfo.h" +#include "SkImageInfo.h" +#include "SkSize.h" +#include "SkStream.h" +#include "SkTypes.h" +#include "SkYUVSizeInfo.h" + +#include + +class SkColorSpace; +class SkColorSpaceXform; +class SkData; +class SkPngChunkReader; +class SkSampler; + +namespace DM { +class CodecSrc; +class ColorCodecSrc; +} +class ColorCodecBench; + +/** + * Abstraction layer directly on top of an image codec. + */ +class SkCodec : SkNoncopyable { +public: + /** + * Minimum number of bytes that must be buffered in SkStream input. + * + * An SkStream passed to NewFromStream must be able to use this many + * bytes to determine the image type. Then the same SkStream must be + * passed to the correct decoder to read from the beginning. + * + * This can be accomplished by implementing peek() to support peeking + * this many bytes, or by implementing rewind() to be able to rewind() + * after reading this many bytes. + */ + static size_t MinBufferedBytesNeeded(); + + /** + * If this stream represents an encoded image that we know how to decode, + * return an SkCodec that can decode it. Otherwise return NULL. + * + * As stated above, this call must be able to peek or read + * MinBufferedBytesNeeded to determine the correct format, and then start + * reading from the beginning. First it will attempt to peek, and it + * assumes that if less than MinBufferedBytesNeeded bytes (but more than + * zero) are returned, this is because the stream is shorter than this, + * so falling back to reading would not provide more data. If peek() + * returns zero bytes, this call will instead attempt to read(). This + * will require that the stream can be rewind()ed. + * + * If SkPngChunkReader is not NULL, take a ref and pass it to libpng if + * the image is a png. + * + * If the SkPngChunkReader is not NULL then: + * If the image is not a PNG, the SkPngChunkReader will be ignored. + * If the image is a PNG, the SkPngChunkReader will be reffed. + * If the PNG has unknown chunks, the SkPngChunkReader will be used + * to handle these chunks. SkPngChunkReader will be called to read + * any unknown chunk at any point during the creation of the codec + * or the decode. Note that if SkPngChunkReader fails to read a + * chunk, this could result in a failure to create the codec or a + * failure to decode the image. + * If the PNG does not contain unknown chunks, the SkPngChunkReader + * will not be used or modified. + * + * If NULL is returned, the stream is deleted immediately. Otherwise, the + * SkCodec takes ownership of it, and will delete it when done with it. + */ + static SkCodec* NewFromStream(SkStream*, SkPngChunkReader* = NULL); + + /** + * If this data represents an encoded image that we know how to decode, + * return an SkCodec that can decode it. Otherwise return NULL. + * + * If the SkPngChunkReader is not NULL then: + * If the image is not a PNG, the SkPngChunkReader will be ignored. + * If the image is a PNG, the SkPngChunkReader will be reffed. + * If the PNG has unknown chunks, the SkPngChunkReader will be used + * to handle these chunks. SkPngChunkReader will be called to read + * any unknown chunk at any point during the creation of the codec + * or the decode. Note that if SkPngChunkReader fails to read a + * chunk, this could result in a failure to create the codec or a + * failure to decode the image. + * If the PNG does not contain unknown chunks, the SkPngChunkReader + * will not be used or modified. + */ + static SkCodec* NewFromData(sk_sp, SkPngChunkReader* = NULL); + static SkCodec* NewFromData(SkData* data, SkPngChunkReader* reader) { + return NewFromData(sk_ref_sp(data), reader); + } + + virtual ~SkCodec(); + + /** + * Return the ImageInfo associated with this codec. + */ + const SkImageInfo& getInfo() const { return fSrcInfo; } + + const SkEncodedInfo& getEncodedInfo() const { return fEncodedInfo; } + + enum Origin { + kTopLeft_Origin = 1, // Default + kTopRight_Origin = 2, // Reflected across y-axis + kBottomRight_Origin = 3, // Rotated 180 + kBottomLeft_Origin = 4, // Reflected across x-axis + kLeftTop_Origin = 5, // Reflected across x-axis, Rotated 90 CCW + kRightTop_Origin = 6, // Rotated 90 CW + kRightBottom_Origin = 7, // Reflected across x-axis, Rotated 90 CW + kLeftBottom_Origin = 8, // Rotated 90 CCW + kDefault_Origin = kTopLeft_Origin, + kLast_Origin = kLeftBottom_Origin, + }; + + /** + * Returns the image orientation stored in the EXIF data. + * If there is no EXIF data, or if we cannot read the EXIF data, returns kTopLeft. + */ + Origin getOrigin() const { return fOrigin; } + + /** + * Return a size that approximately supports the desired scale factor. + * The codec may not be able to scale efficiently to the exact scale + * factor requested, so return a size that approximates that scale. + * The returned value is the codec's suggestion for the closest valid + * scale that it can natively support + */ + SkISize getScaledDimensions(float desiredScale) const { + // Negative and zero scales are errors. + SkASSERT(desiredScale > 0.0f); + if (desiredScale <= 0.0f) { + return SkISize::Make(0, 0); + } + + // Upscaling is not supported. Return the original size if the client + // requests an upscale. + if (desiredScale >= 1.0f) { + return this->getInfo().dimensions(); + } + return this->onGetScaledDimensions(desiredScale); + } + + /** + * Return (via desiredSubset) a subset which can decoded from this codec, + * or false if this codec cannot decode subsets or anything similar to + * desiredSubset. + * + * @param desiredSubset In/out parameter. As input, a desired subset of + * the original bounds (as specified by getInfo). If true is returned, + * desiredSubset may have been modified to a subset which is + * supported. Although a particular change may have been made to + * desiredSubset to create something supported, it is possible other + * changes could result in a valid subset. + * If false is returned, desiredSubset's value is undefined. + * @return true if this codec supports decoding desiredSubset (as + * returned, potentially modified) + */ + bool getValidSubset(SkIRect* desiredSubset) const { + return this->onGetValidSubset(desiredSubset); + } + + /** + * Format of the encoded data. + */ + SkEncodedImageFormat getEncodedFormat() const { return this->onGetEncodedFormat(); } + + /** + * Used to describe the result of a call to getPixels(). + * + * Result is the union of possible results from subclasses. + */ + enum Result { + /** + * General return value for success. + */ + kSuccess, + /** + * The input is incomplete. A partial image was generated. + */ + kIncompleteInput, + /** + * The generator cannot convert to match the request, ignoring + * dimensions. + */ + kInvalidConversion, + /** + * The generator cannot scale to requested size. + */ + kInvalidScale, + /** + * Parameters (besides info) are invalid. e.g. NULL pixels, rowBytes + * too small, etc. + */ + kInvalidParameters, + /** + * The input did not contain a valid image. + */ + kInvalidInput, + /** + * Fulfilling this request requires rewinding the input, which is not + * supported for this input. + */ + kCouldNotRewind, + /** + * This method is not implemented by this codec. + * FIXME: Perhaps this should be kUnsupported? + */ + kUnimplemented, + }; + + /** + * Whether or not the memory passed to getPixels is zero initialized. + */ + enum ZeroInitialized { + /** + * The memory passed to getPixels is zero initialized. The SkCodec + * may take advantage of this by skipping writing zeroes. + */ + kYes_ZeroInitialized, + /** + * The memory passed to getPixels has not been initialized to zero, + * so the SkCodec must write all zeroes to memory. + * + * This is the default. It will be used if no Options struct is used. + */ + kNo_ZeroInitialized, + }; + + /** + * Additional options to pass to getPixels. + */ + struct Options { + Options() + : fZeroInitialized(kNo_ZeroInitialized) + , fSubset(nullptr) + , fFrameIndex(0) + , fHasPriorFrame(false) + {} + + ZeroInitialized fZeroInitialized; + /** + * If not NULL, represents a subset of the original image to decode. + * Must be within the bounds returned by getInfo(). + * If the EncodedFormat is SkEncodedImageFormat::kWEBP (the only one which + * currently supports subsets), the top and left values must be even. + * + * In getPixels and incremental decode, we will attempt to decode the + * exact rectangular subset specified by fSubset. + * + * In a scanline decode, it does not make sense to specify a subset + * top or subset height, since the client already controls which rows + * to get and which rows to skip. During scanline decodes, we will + * require that the subset top be zero and the subset height be equal + * to the full height. We will, however, use the values of + * subset left and subset width to decode partial scanlines on calls + * to getScanlines(). + */ + const SkIRect* fSubset; + + /** + * The frame to decode. + * + * Only meaningful for multi-frame images. + */ + size_t fFrameIndex; + + /** + * If true, the dst already contains the prior frame. + * + * Only meaningful for multi-frame images. + * + * If fFrameIndex needs to be blended with a prior frame (as reported by + * getFrameInfo[fFrameIndex].fRequiredFrame), the client can set this to + * either true or false: + * + * true means that the prior frame is already in the dst, and this + * codec only needs to decode fFrameIndex and blend it with the dst. + * Options.fZeroInitialized is ignored in this case. + * + * false means that the dst does not contain the prior frame, so this + * codec needs to first decode the prior frame (which in turn may need + * to decode its prior frame). + */ + bool fHasPriorFrame; + }; + + /** + * Decode into the given pixels, a block of memory of size at + * least (info.fHeight - 1) * rowBytes + (info.fWidth * + * bytesPerPixel) + * + * Repeated calls to this function should give the same results, + * allowing the PixelRef to be immutable. + * + * @param info A description of the format (config, size) + * expected by the caller. This can simply be identical + * to the info returned by getInfo(). + * + * This contract also allows the caller to specify + * different output-configs, which the implementation can + * decide to support or not. + * + * A size that does not match getInfo() implies a request + * to scale. If the generator cannot perform this scale, + * it will return kInvalidScale. + * + * If the info contains a non-null SkColorSpace, the codec + * will perform the appropriate color space transformation. + * If the caller passes in the same color space that was + * reported by the codec, the color space transformation is + * a no-op. + * + * If info is kIndex8_SkColorType, then the caller must provide storage for up to 256 + * SkPMColor values in ctable. On success the generator must copy N colors into that storage, + * (where N is the logical number of table entries) and set ctableCount to N. + * + * If info is not kIndex8_SkColorType, then the last two parameters may be NULL. If ctableCount + * is not null, it will be set to 0. + * + * If a scanline decode is in progress, scanline mode will end, requiring the client to call + * startScanlineDecode() in order to return to decoding scanlines. + * + * @return Result kSuccess, or another value explaining the type of failure. + */ + Result getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, const Options*, + SkPMColor ctable[], int* ctableCount); + + /** + * Simplified version of getPixels() that asserts that info is NOT kIndex8_SkColorType and + * uses the default Options. + */ + Result getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes); + + /** + * If decoding to YUV is supported, this returns true. Otherwise, this + * returns false and does not modify any of the parameters. + * + * @param sizeInfo Output parameter indicating the sizes and required + * allocation widths of the Y, U, and V planes. + * @param colorSpace Output parameter. If non-NULL this is set to kJPEG, + * otherwise this is ignored. + */ + bool queryYUV8(SkYUVSizeInfo* sizeInfo, SkYUVColorSpace* colorSpace) const { + if (nullptr == sizeInfo) { + return false; + } + + return this->onQueryYUV8(sizeInfo, colorSpace); + } + + /** + * Returns kSuccess, or another value explaining the type of failure. + * This always attempts to perform a full decode. If the client only + * wants size, it should call queryYUV8(). + * + * @param sizeInfo Needs to exactly match the values returned by the + * query, except the WidthBytes may be larger than the + * recommendation (but not smaller). + * @param planes Memory for each of the Y, U, and V planes. + */ + Result getYUV8Planes(const SkYUVSizeInfo& sizeInfo, void* planes[3]) { + if (nullptr == planes || nullptr == planes[0] || nullptr == planes[1] || + nullptr == planes[2]) { + return kInvalidInput; + } + + if (!this->rewindIfNeeded()) { + return kCouldNotRewind; + } + + return this->onGetYUV8Planes(sizeInfo, planes); + } + + /** + * Prepare for an incremental decode with the specified options. + * + * This may require a rewind. + * + * @param dstInfo Info of the destination. If the dimensions do not match + * those of getInfo, this implies a scale. + * @param dst Memory to write to. Needs to be large enough to hold the subset, + * if present, or the full image as described in dstInfo. + * @param options Contains decoding options, including if memory is zero + * initialized and whether to decode a subset. + * @param ctable A pointer to a color table. When dstInfo.colorType() is + * kIndex8, this should be non-NULL and have enough storage for 256 + * colors. The color table will be populated after decoding the palette. + * @param ctableCount A pointer to the size of the color table. When + * dstInfo.colorType() is kIndex8, this should be non-NULL. It will + * be modified to the true size of the color table (<= 256) after + * decoding the palette. + * @return Enum representing success or reason for failure. + */ + Result startIncrementalDecode(const SkImageInfo& dstInfo, void* dst, size_t rowBytes, + const SkCodec::Options*, SkPMColor* ctable, int* ctableCount); + + Result startIncrementalDecode(const SkImageInfo& dstInfo, void* dst, size_t rowBytes, + const SkCodec::Options* options) { + return this->startIncrementalDecode(dstInfo, dst, rowBytes, options, nullptr, nullptr); + } + + Result startIncrementalDecode(const SkImageInfo& dstInfo, void* dst, size_t rowBytes) { + return this->startIncrementalDecode(dstInfo, dst, rowBytes, nullptr, nullptr, nullptr); + } + + /** + * Start/continue the incremental decode. + * + * Not valid to call before calling startIncrementalDecode(). + * + * After the first call, should only be called again if more data has been + * provided to the source SkStream. + * + * Unlike getPixels and getScanlines, this does not do any filling. This is + * left up to the caller, since they may be skipping lines or continuing the + * decode later. In the latter case, they may choose to initialize all lines + * first, or only initialize the remaining lines after the first call. + * + * @param rowsDecoded Optional output variable returning the total number of + * lines initialized. Only meaningful if this method returns kIncompleteInput. + * Otherwise the implementation may not set it. + * Note that some implementations may have initialized this many rows, but + * not necessarily finished those rows (e.g. interlaced PNG). This may be + * useful for determining what rows the client needs to initialize. + * @return kSuccess if all lines requested in startIncrementalDecode have + * been completely decoded. kIncompleteInput otherwise. + */ + Result incrementalDecode(int* rowsDecoded = nullptr) { + if (!fStartedIncrementalDecode) { + return kInvalidParameters; + } + return this->onIncrementalDecode(rowsDecoded); + } + + /** + * The remaining functions revolve around decoding scanlines. + */ + + /** + * Prepare for a scanline decode with the specified options. + * + * After this call, this class will be ready to decode the first scanline. + * + * This must be called in order to call getScanlines or skipScanlines. + * + * This may require rewinding the stream. + * + * Not all SkCodecs support this. + * + * @param dstInfo Info of the destination. If the dimensions do not match + * those of getInfo, this implies a scale. + * @param options Contains decoding options, including if memory is zero + * initialized. + * @param ctable A pointer to a color table. When dstInfo.colorType() is + * kIndex8, this should be non-NULL and have enough storage for 256 + * colors. The color table will be populated after decoding the palette. + * @param ctableCount A pointer to the size of the color table. When + * dstInfo.colorType() is kIndex8, this should be non-NULL. It will + * be modified to the true size of the color table (<= 256) after + * decoding the palette. + * @return Enum representing success or reason for failure. + */ + Result startScanlineDecode(const SkImageInfo& dstInfo, const SkCodec::Options* options, + SkPMColor ctable[], int* ctableCount); + + /** + * Simplified version of startScanlineDecode() that asserts that info is NOT + * kIndex8_SkColorType and uses the default Options. + */ + Result startScanlineDecode(const SkImageInfo& dstInfo); + + /** + * Write the next countLines scanlines into dst. + * + * Not valid to call before calling startScanlineDecode(). + * + * @param dst Must be non-null, and large enough to hold countLines + * scanlines of size rowBytes. + * @param countLines Number of lines to write. + * @param rowBytes Number of bytes per row. Must be large enough to hold + * a scanline based on the SkImageInfo used to create this object. + * @return the number of lines successfully decoded. If this value is + * less than countLines, this will fill the remaining lines with a + * default value. + */ + int getScanlines(void* dst, int countLines, size_t rowBytes); + + /** + * Skip count scanlines. + * + * Not valid to call before calling startScanlineDecode(). + * + * The default version just calls onGetScanlines and discards the dst. + * NOTE: If skipped lines are the only lines with alpha, this default + * will make reallyHasAlpha return true, when it could have returned + * false. + * + * @return true if the scanlines were successfully skipped + * false on failure, possible reasons for failure include: + * An incomplete input image stream. + * Calling this function before calling startScanlineDecode(). + * If countLines is less than zero or so large that it moves + * the current scanline past the end of the image. + */ + bool skipScanlines(int countLines); + + /** + * The order in which rows are output from the scanline decoder is not the + * same for all variations of all image types. This explains the possible + * output row orderings. + */ + enum SkScanlineOrder { + /* + * By far the most common, this indicates that the image can be decoded + * reliably using the scanline decoder, and that rows will be output in + * the logical order. + */ + kTopDown_SkScanlineOrder, + + /* + * This indicates that the scanline decoder reliably outputs rows, but + * they will be returned in reverse order. If the scanline format is + * kBottomUp, the nextScanline() API can be used to determine the actual + * y-coordinate of the next output row, but the client is not forced + * to take advantage of this, given that it's not too tough to keep + * track independently. + * + * For full image decodes, it is safe to get all of the scanlines at + * once, since the decoder will handle inverting the rows as it + * decodes. + * + * For subset decodes and sampling, it is simplest to get and skip + * scanlines one at a time, using the nextScanline() API. It is + * possible to ask for larger chunks at a time, but this should be used + * with caution. As with full image decodes, the decoder will handle + * inverting the requested rows, but rows will still be delivered + * starting from the bottom of the image. + * + * Upside down bmps are an example. + */ + kBottomUp_SkScanlineOrder, + }; + + /** + * An enum representing the order in which scanlines will be returned by + * the scanline decoder. + * + * This is undefined before startScanlineDecode() is called. + */ + SkScanlineOrder getScanlineOrder() const { return this->onGetScanlineOrder(); } + + /** + * Returns the y-coordinate of the next row to be returned by the scanline + * decoder. + * + * This will equal fCurrScanline, except in the case of strangely + * encoded image types (bottom-up bmps). + * + * Results are undefined when not in scanline decoding mode. + */ + int nextScanline() const { return this->outputScanline(fCurrScanline); } + + /** + * Returns the output y-coordinate of the row that corresponds to an input + * y-coordinate. The input y-coordinate represents where the scanline + * is located in the encoded data. + * + * This will equal inputScanline, except in the case of strangely + * encoded image types (bottom-up bmps, interlaced gifs). + */ + int outputScanline(int inputScanline) const; + + // The required frame for an independent frame is marked as + // kNone. + static constexpr size_t kNone = static_cast(-1); + + /** + * Information about individual frames in a multi-framed image. + */ + struct FrameInfo { + /** + * The frame that this frame needs to be blended with, or + * kNone. + */ + size_t fRequiredFrame; + + /** + * Number of milliseconds to show this frame. + */ + size_t fDuration; + }; + + /** + * Return info about the frames in the image. + * + * May require reading through the stream to determine info about the + * frames (including the count). + * + * As such, future decoding calls may require a rewind. + * + * For single-frame images, this will return an empty vector. + */ + std::vector getFrameInfo() { + return this->onGetFrameInfo(); + } + + static constexpr int kRepetitionCountInfinite = -1; + + /** + * Return the number of times to repeat, if this image is animated. + * + * May require reading the stream to find the repetition count. + * + * As such, future decoding calls may require a rewind. + * + * For single-frame images, this will return 0. + */ + int getRepetitionCount() { + return this->onGetRepetitionCount(); + } + +protected: + /** + * Takes ownership of SkStream* + */ + SkCodec(int width, + int height, + const SkEncodedInfo&, + SkStream*, + sk_sp, + Origin = kTopLeft_Origin); + + /** + * Takes ownership of SkStream* + * Allows the subclass to set the recommended SkImageInfo + */ + SkCodec(const SkEncodedInfo&, + const SkImageInfo&, + SkStream*, + Origin = kTopLeft_Origin); + + virtual SkISize onGetScaledDimensions(float /*desiredScale*/) const { + // By default, scaling is not supported. + return this->getInfo().dimensions(); + } + + // FIXME: What to do about subsets?? + /** + * Subclasses should override if they support dimensions other than the + * srcInfo's. + */ + virtual bool onDimensionsSupported(const SkISize&) { + return false; + } + + virtual SkEncodedImageFormat onGetEncodedFormat() const = 0; + + /** + * @param rowsDecoded When the encoded image stream is incomplete, this function + * will return kIncompleteInput and rowsDecoded will be set to + * the number of scanlines that were successfully decoded. + * This will allow getPixels() to fill the uninitialized memory. + */ + virtual Result onGetPixels(const SkImageInfo& info, + void* pixels, size_t rowBytes, const Options&, + SkPMColor ctable[], int* ctableCount, + int* rowsDecoded) = 0; + + virtual bool onQueryYUV8(SkYUVSizeInfo*, SkYUVColorSpace*) const { + return false; + } + + virtual Result onGetYUV8Planes(const SkYUVSizeInfo&, void*[3] /*planes*/) { + return kUnimplemented; + } + + virtual bool onGetValidSubset(SkIRect* /*desiredSubset*/) const { + // By default, subsets are not supported. + return false; + } + + /** + * If the stream was previously read, attempt to rewind. + * + * If the stream needed to be rewound, call onRewind. + * @returns true if the codec is at the right position and can be used. + * false if there was a failure to rewind. + * + * This is called by getPixels() and start(). Subclasses may call if they + * need to rewind at another time. + */ + bool SK_WARN_UNUSED_RESULT rewindIfNeeded(); + + /** + * Called by rewindIfNeeded, if the stream needed to be rewound. + * + * Subclasses should do any set up needed after a rewind. + */ + virtual bool onRewind() { + return true; + } + + /** + * On an incomplete input, getPixels() and getScanlines() will fill any uninitialized + * scanlines. This allows the subclass to indicate what value to fill with. + * + * @param dstInfo Describes the destination. + * @return The value with which to fill uninitialized pixels. + * + * Note that we can interpret the return value as a 64-bit Float16 color, a SkPMColor, + * a 16-bit 565 color, an 8-bit gray color, or an 8-bit index into a color table, + * depending on the color type. + */ + uint64_t getFillValue(const SkImageInfo& dstInfo) const { + return this->onGetFillValue(dstInfo); + } + + /** + * Some subclasses will override this function, but this is a useful default for the color + * types that we support. Note that for color types that do not use the full 64-bits, + * we will simply take the low bits of the fill value. + * + * The defaults are: + * kRGBA_F16_SkColorType: Transparent or Black, depending on the src alpha type + * kN32_SkColorType: Transparent or Black, depending on the src alpha type + * kRGB_565_SkColorType: Black + * kGray_8_SkColorType: Black + * kIndex_8_SkColorType: First color in color table + */ + virtual uint64_t onGetFillValue(const SkImageInfo& dstInfo) const; + + /** + * Get method for the input stream + */ + SkStream* stream() { + return fStream.get(); + } + + /** + * The remaining functions revolve around decoding scanlines. + */ + + /** + * Most images types will be kTopDown and will not need to override this function. + */ + virtual SkScanlineOrder onGetScanlineOrder() const { return kTopDown_SkScanlineOrder; } + + const SkImageInfo& dstInfo() const { return fDstInfo; } + + const SkCodec::Options& options() const { return fOptions; } + + /** + * Returns the number of scanlines that have been decoded so far. + * This is unaffected by the SkScanlineOrder. + * + * Returns -1 if we have not started a scanline decode. + */ + int currScanline() const { return fCurrScanline; } + + virtual int onOutputScanline(int inputScanline) const; + + bool initializeColorXform(const SkImageInfo& dstInfo); + SkColorSpaceXform* colorXform() const { return fColorXform.get(); } + + virtual std::vector onGetFrameInfo() { + // empty vector - this is not animated. + return {}; + } + + virtual int onGetRepetitionCount() { + return 0; + } + +private: + const SkEncodedInfo fEncodedInfo; + const SkImageInfo fSrcInfo; + std::unique_ptr fStream; + bool fNeedsRewind; + const Origin fOrigin; + + SkImageInfo fDstInfo; + SkCodec::Options fOptions; + std::unique_ptr fColorXform; + + // Only meaningful during scanline decodes. + int fCurrScanline; + + bool fStartedIncrementalDecode; + + /** + * Return whether these dimensions are supported as a scale. + * + * The codec may choose to cache the information about scale and subset. + * Either way, the same information will be passed to onGetPixels/onStart + * on success. + * + * This must return true for a size returned from getScaledDimensions. + */ + bool dimensionsSupported(const SkISize& dim) { + return dim == fSrcInfo.dimensions() || this->onDimensionsSupported(dim); + } + + // Methods for scanline decoding. + virtual SkCodec::Result onStartScanlineDecode(const SkImageInfo& /*dstInfo*/, + const SkCodec::Options& /*options*/, SkPMColor* /*ctable*/, int* /*ctableCount*/) { + return kUnimplemented; + } + + virtual Result onStartIncrementalDecode(const SkImageInfo& /*dstInfo*/, void*, size_t, + const SkCodec::Options&, SkPMColor*, int*) { + return kUnimplemented; + } + + virtual Result onIncrementalDecode(int*) { + return kUnimplemented; + } + + + virtual bool onSkipScanlines(int /*countLines*/) { return false; } + + virtual int onGetScanlines(void* /*dst*/, int /*countLines*/, size_t /*rowBytes*/) { return 0; } + + /** + * On an incomplete decode, getPixels() and getScanlines() will call this function + * to fill any uinitialized memory. + * + * @param dstInfo Contains the destination color type + * Contains the destination alpha type + * Contains the destination width + * The height stored in this info is unused + * @param dst Pointer to the start of destination pixel memory + * @param rowBytes Stride length in destination pixel memory + * @param zeroInit Indicates if memory is zero initialized + * @param linesRequested Number of lines that the client requested + * @param linesDecoded Number of lines that were successfully decoded + */ + void fillIncompleteImage(const SkImageInfo& dstInfo, void* dst, size_t rowBytes, + ZeroInitialized zeroInit, int linesRequested, int linesDecoded); + + /** + * Return an object which will allow forcing scanline decodes to sample in X. + * + * May create a sampler, if one is not currently being used. Otherwise, does + * not affect ownership. + * + * Only valid during scanline decoding or incremental decoding. + */ + virtual SkSampler* getSampler(bool /*createIfNecessary*/) { return nullptr; } + + friend class DM::CodecSrc; // for fillIncompleteImage + friend class SkSampledCodec; + friend class SkIcoCodec; +}; +#endif // SkCodec_DEFINED diff --git a/libskia/include/codec/SkEncodedInfo.h b/libskia/include/codec/SkEncodedInfo.h new file mode 100644 index 00000000..eb8c147a --- /dev/null +++ b/libskia/include/codec/SkEncodedInfo.h @@ -0,0 +1,199 @@ +/* + * Copyright 2016 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkEncodedInfo_DEFINED +#define SkEncodedInfo_DEFINED + +#include "SkImageInfo.h" + +class SkColorSpace; + +struct SkEncodedInfo { +public: + + enum Alpha { + kOpaque_Alpha, + kUnpremul_Alpha, + + // Each pixel is either fully opaque or fully transparent. + // There is no difference between requesting kPremul or kUnpremul. + kBinary_Alpha, + }; + + /* + * We strive to make the number of components per pixel obvious through + * our naming conventions. + * Ex: kRGB has 3 components. kRGBA has 4 components. + * + * This sometimes results in redundant Alpha and Color information. + * Ex: kRGB images must also be kOpaque. + */ + enum Color { + // PNG, WBMP + kGray_Color, + + // PNG + kGrayAlpha_Color, + + // PNG, GIF, BMP + kPalette_Color, + + // PNG, RAW + kRGB_Color, + kRGBA_Color, + + // BMP + kBGR_Color, + kBGRX_Color, + kBGRA_Color, + + // JPEG, WEBP + kYUV_Color, + + // WEBP + kYUVA_Color, + + // JPEG + // Photoshop actually writes inverted CMYK data into JPEGs, where zero + // represents 100% ink coverage. For this reason, we treat CMYK JPEGs + // as having inverted CMYK. libjpeg-turbo warns that this may break + // other applications, but the CMYK JPEGs we see on the web expect to + // be treated as inverted CMYK. + kInvertedCMYK_Color, + kYCCK_Color, + }; + + static SkEncodedInfo Make(Color color, Alpha alpha, int bitsPerComponent) { + SkASSERT(1 == bitsPerComponent || + 2 == bitsPerComponent || + 4 == bitsPerComponent || + 8 == bitsPerComponent || + 16 == bitsPerComponent); + + switch (color) { + case kGray_Color: + SkASSERT(kOpaque_Alpha == alpha); + break; + case kGrayAlpha_Color: + SkASSERT(kOpaque_Alpha != alpha); + break; + case kPalette_Color: + SkASSERT(16 != bitsPerComponent); + break; + case kRGB_Color: + case kBGR_Color: + case kBGRX_Color: + SkASSERT(kOpaque_Alpha == alpha); + SkASSERT(bitsPerComponent >= 8); + break; + case kYUV_Color: + case kInvertedCMYK_Color: + case kYCCK_Color: + SkASSERT(kOpaque_Alpha == alpha); + SkASSERT(8 == bitsPerComponent); + break; + case kRGBA_Color: + SkASSERT(kOpaque_Alpha != alpha); + SkASSERT(bitsPerComponent >= 8); + break; + case kBGRA_Color: + case kYUVA_Color: + SkASSERT(kOpaque_Alpha != alpha); + SkASSERT(8 == bitsPerComponent); + break; + default: + SkASSERT(false); + break; + } + + return SkEncodedInfo(color, alpha, bitsPerComponent); + } + + /* + * Returns an SkImageInfo with Skia color and alpha types that are the + * closest possible match to the encoded info. + */ + SkImageInfo makeImageInfo(int width, int height, sk_sp colorSpace) const { + switch (fColor) { + case kGray_Color: + SkASSERT(kOpaque_Alpha == fAlpha); + return SkImageInfo::Make(width, height, kGray_8_SkColorType, + kOpaque_SkAlphaType, colorSpace); + case kGrayAlpha_Color: + SkASSERT(kOpaque_Alpha != fAlpha); + return SkImageInfo::Make(width, height, kN32_SkColorType, + kUnpremul_SkAlphaType, colorSpace); + case kPalette_Color: { + SkAlphaType alphaType = (kOpaque_Alpha == fAlpha) ? kOpaque_SkAlphaType : + kUnpremul_SkAlphaType; + return SkImageInfo::Make(width, height, kIndex_8_SkColorType, + alphaType, colorSpace); + } + case kRGB_Color: + case kBGR_Color: + case kBGRX_Color: + case kYUV_Color: + case kInvertedCMYK_Color: + case kYCCK_Color: + SkASSERT(kOpaque_Alpha == fAlpha); + return SkImageInfo::Make(width, height, kN32_SkColorType, + kOpaque_SkAlphaType, colorSpace); + case kRGBA_Color: + case kBGRA_Color: + case kYUVA_Color: + SkASSERT(kOpaque_Alpha != fAlpha); + return SkImageInfo::Make(width, height, kN32_SkColorType, + kUnpremul_SkAlphaType, std::move(colorSpace)); + default: + SkASSERT(false); + return SkImageInfo::MakeUnknown(); + } + } + + Color color() const { return fColor; } + Alpha alpha() const { return fAlpha; } + uint8_t bitsPerComponent() const { return fBitsPerComponent; } + + uint8_t bitsPerPixel() const { + switch (fColor) { + case kGray_Color: + return fBitsPerComponent; + case kGrayAlpha_Color: + return 2 * fBitsPerComponent; + case kPalette_Color: + return fBitsPerComponent; + case kRGB_Color: + case kBGR_Color: + case kYUV_Color: + return 3 * fBitsPerComponent; + case kRGBA_Color: + case kBGRA_Color: + case kBGRX_Color: + case kYUVA_Color: + case kInvertedCMYK_Color: + case kYCCK_Color: + return 4 * fBitsPerComponent; + default: + SkASSERT(false); + return 0; + } + } + +private: + + SkEncodedInfo(Color color, Alpha alpha, uint8_t bitsPerComponent) + : fColor(color) + , fAlpha(alpha) + , fBitsPerComponent(bitsPerComponent) + {} + + Color fColor; + Alpha fAlpha; + uint8_t fBitsPerComponent; +}; + +#endif diff --git a/libskia/include/config/SkUserConfig.h b/libskia/include/config/SkUserConfig.h index 382f8912..07294479 100644 --- a/libskia/include/config/SkUserConfig.h +++ b/libskia/include/config/SkUserConfig.h @@ -37,22 +37,6 @@ /////////////////////////////////////////////////////////////////////////////// -/* Scalars (the fractional value type in skia) can be implemented either as - floats or 16.16 integers (fixed). Exactly one of these two symbols must be - defined. -*/ -//#define SK_SCALAR_IS_FLOAT -//#define SK_SCALAR_IS_FIXED - - -/* For some performance-critical scalar operations, skia will optionally work - around the standard float operators if it knows that the CPU does not have - native support for floats. If your environment uses software floating point, - define this flag. - */ -//#define SK_SOFTWARE_FLOAT - - /* Skia has lots of debug-only code. Often this is just null checks or other parameter checking, but sometimes it can be quite intrusive (e.g. check that each 32bit pixel is in premultiplied form). This code can be very useful @@ -74,20 +58,6 @@ //#define SK_DEBUG_GLYPH_CACHE //#define SK_DEBUG_PATH -/* To assist debugging, Skia provides an instance counting utility in - include/core/SkInstCount.h. This flag turns on and off that utility to - allow instance count tracking in either debug or release builds. By - default it is enabled in debug but disabled in release. - */ -//#define SK_ENABLE_INST_COUNT 1 - -/* If, in debugging mode, Skia needs to stop (presumably to invoke a debugger) - it will call SK_CRASH(). If this is not defined it, it is defined in - SkPostConfig.h to write to an illegal address - */ -//#define SK_CRASH() *(int *)(uintptr_t)0 = 0 - - /* preconfig will have attempted to determine the endianness of the system, but you can change these mutually exclusive flags here. */ @@ -104,12 +74,6 @@ //#define SK_UINT8_BITFIELD_LENDIAN -/* Some compilers don't support long long for 64bit integers. If yours does - not, define this to the appropriate type. - */ -//#define SkLONGLONG int64_t - - /* To write debug messages to a console, skia will call SkDebugf(...) following printf conventions (e.g. const char* format, ...). If you want to redirect this to something other than printf, define yours here @@ -129,22 +93,9 @@ */ //#define SK_DEFAULT_IMAGE_CACHE_LIMIT (1024 * 1024) -/* If zlib is available and you want to support the flate compression - algorithm (used in PDF generation), define SK_ZLIB_INCLUDE to be the - include path. Alternatively, define SK_SYSTEM_ZLIB to use the system zlib - library specified as "#include ". - */ -//#define SK_ZLIB_INCLUDE -//#define SK_SYSTEM_ZLIB - -/* Define this to allow PDF scalars above 32k. The PDF/A spec doesn't allow - them, but modern PDF interpreters should handle them just fine. - */ -//#define SK_ALLOW_LARGE_PDF_SCALARS - /* Define this to provide font subsetter in PDF generation. */ -//#define SK_SFNTLY_SUBSETTER "sfntly/subsetter/font_subsetter.h" +//#define SK_SFNTLY_SUBSETTER "sample/chromium/font_subsetter.h" /* Define this to set the upper limit for text to support LCD. Values that are very large increase the cost in the font cache and draw slower, without @@ -161,26 +112,14 @@ //#define SK_SUPPORT_UNITTEST #endif -/* If your system embeds skia and has complex event logging, define this - symbol to name a file that maps the following macros to your system's - equivalents: - SK_TRACE_EVENT0(event) - SK_TRACE_EVENT1(event, name1, value1) - SK_TRACE_EVENT2(event, name1, value1, name2, value2) - src/utils/SkDebugTrace.h has a trivial implementation that writes to - the debug output stream. If SK_USER_TRACE_INCLUDE_FILE is not defined, - SkTrace.h will define the above three macros to do nothing. -*/ -//#undef SK_USER_TRACE_INCLUDE_FILE - /* Change the ordering to work in X windows. */ -/*#ifdef SK_SAMPLES_FOR_X +#ifdef SK_SAMPLES_FOR_X #define SK_R32_SHIFT 16 #define SK_G32_SHIFT 8 #define SK_B32_SHIFT 0 #define SK_A32_SHIFT 24 -#endif*/ +#endif /* Determines whether to build code that supports the GPU backend. Some classes @@ -190,70 +129,14 @@ directories from your include search path when you're not building the GPU backend. Defaults to 1 (build the GPU code). */ -#define SK_SUPPORT_GPU 0 +//#define SK_SUPPORT_GPU 1 -/* The PDF generation code uses Path Ops to generate inverse fills and complex - * clipping paths, but at this time, Path Ops is not release ready yet. So, - * the code is hidden behind this #define guard. If you are feeling adventurous - * and want the latest and greatest PDF generation code, uncomment the #define. - * When Path Ops is release ready, the define guards and this user config - * define should be removed entirely. +/* Skia makes use of histogram logging macros to trace the frequency of + * events. By default, Skia provides no-op versions of these macros. + * Skia consumers can provide their own definitions of these macros to + * integrate with their histogram collection backend. */ -//#define SK_PDF_USE_PATHOPS - -// FG-2014-09-26: [[ Bugfix 11968 ]] PowerPC uses the same build order as x86 -// Mac platforms (just with the bytes reversed). -#if defined(SK_BUILD_FOR_MAC) - // MM-2014-02-05: [[ RefactorGraphics ]] Fiddled with byte order. - #define SK_R32_SHIFT 16 - #define SK_G32_SHIFT 8 - #define SK_B32_SHIFT 0 - #define SK_A32_SHIFT 24 -#elif defined(SK_BUILD_FOR_IOS) || defined(SK_BUILD_FOR_UNIX) - // IM-2013-08-21: [[ RefactorGraphics ]] Use GL byte order for iOS - // FG-2014-07-17: [[ LinuxGDK ]] Use GDK byte order - #define SK_R32_SHIFT 0 - #define SK_G32_SHIFT 8 - #define SK_B32_SHIFT 16 - #define SK_A32_SHIFT 24 -#endif - -// MM-2014-01-09: [[ RefactorGraphics ]] SkAtomics_sync.h doesn't appear to compile on Linux. -#if defined(SK_BUILD_FOR_UNIX) - #define SK_ATOMICS_PLATFORM_H "../../src/ports/SkAtomics_sync.h" -#endif - -// MM-2014-01-14: [[ RefactorGraphics ]] SK_FONTHOST_DOES_NOT_USE_FONTMGR is required for fonr support on Android. -#if defined(SK_BUILD_FOR_ANDROID) - #define SK_FONTHOST_DOES_NOT_USE_FONTMGR -#endif - -#ifdef SK_BUILD_FOR_WIN32 - // MM-2014-01-17: [[ RefactorGraphics ]] Define SK_RESTRICT to empty to prevent VS 2005 from complaining. - #if defined(SK_RESTRICT) - #undef SK_RESTRICT - #endif - #define SK_RESTRICT - - // MM-2014-01-17: [[ RefactorGraphics ]] Workaround to prevent VS 2005 from complaing when both windows.h and intrin.h are included. - // Taken from http://blog.assarbad.net/20120425/annoyance-in-the-windows-sdk-headers/ and - // https://developer.mozilla.org/en-US/docs/Developer_Guide/Build_Instructions/Intrin.h - #if _MSC_VER >= 1400 - #pragma push_macro("_interlockedbittestandset") - #pragma push_macro("_interlockedbittestandreset") - #pragma push_macro("_interlockedbittestandset64") - #pragma push_macro("_interlockedbittestandreset64") - #define _interlockedbittestandset _local_interlockedbittestandset - #define _interlockedbittestandreset _local_interlockedbittestandreset - #define _interlockedbittestandset64 _local_interlockedbittestandset64 - #define _interlockedbittestandreset64 _local_interlockedbittestandreset64 - #include - #pragma pop_macro("_interlockedbittestandreset64") - #pragma pop_macro("_interlockedbittestandset64") - #pragma pop_macro("_interlockedbittestandreset") - #pragma pop_macro("_interlockedbittestandset") - #pragma intrinsic(_ReadWriteBarrier) - #endif -#endif +//#define SK_HISTOGRAM_BOOLEAN(name, value) +//#define SK_HISTOGRAM_ENUMERATION(name, value, boundary_value) #endif diff --git a/libskia/include/config/sk_stdint.h b/libskia/include/config/sk_stdint.h deleted file mode 100644 index 9a6118bd..00000000 --- a/libskia/include/config/sk_stdint.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/libskia/include/core/Sk64.h b/libskia/include/core/Sk64.h deleted file mode 100644 index 786b1e2f..00000000 --- a/libskia/include/core/Sk64.h +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright 2006 The Android Open Source Project - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef Sk64_DEFINED -#define Sk64_DEFINED - -#include "SkTypes.h" - -/** \class Sk64 - - Sk64 is a 64-bit math package that does not require long long support from the compiler. -*/ -struct SK_API Sk64 { -public: - - // MM-2014-01-09: [[ RefactorGraphics ]] Made fHi and fLo public in order to appease compiler. - int32_t fHi; //!< the high 32 bits of the number (including sign) - uint32_t fLo; //!< the low 32 bits of the number - - int32_t hi() const { return fHi; } - uint32_t lo() const { return fLo; } - - int64_t as64() const { return ((int64_t)fHi << 32) | fLo; } - int64_t getLongLong() const { return this->as64(); } - - void set64(int64_t value) { - fHi = (int32_t)(value >> 32); - fLo = (uint32_t)value; - } - - /** Returns non-zero if the Sk64 can be represented as a signed 32 bit integer - */ - SkBool is32() const { return fHi == ((int32_t)fLo >> 31); } - - /** Returns non-zero if the Sk64 cannot be represented as a signed 32 bit integer - */ - SkBool is64() const { return fHi != ((int32_t)fLo >> 31); } - - /** Return the signed 32 bit integer equivalent. Asserts that is32() returns non-zero. - */ - int32_t get32() const { SkASSERT(this->is32()); return (int32_t)fLo; } - - /** Returns the square-root of the number as a signed 32 bit value. */ - int32_t getSqrt() const; - - /** Returns the number of leading zeros of the absolute value of this. - Will return in the range [0..64] - */ - int getClzAbs() const; - - /** Returns non-zero if the number is zero */ - SkBool isZero() const { return (fHi | fLo) == 0; } - - /** Returns non-zero if the number is non-zero */ - SkBool nonZero() const { return fHi | fLo; } - - /** Returns non-zero if the number is negative (number < 0) */ - SkBool isNeg() const { return (uint32_t)fHi >> 31; } - - /** Returns non-zero if the number is positive (number > 0) */ - SkBool isPos() const { return ~(fHi >> 31) & (fHi | fLo); } - - /** Returns -1,0,+1 based on the sign of the number */ - int getSign() const { return (fHi >> 31) | Sk32ToBool(fHi | fLo); } - - /** Negate the number */ - void negate(); - - /** If the number < 0, negate the number - */ - void abs(); - - /** Returns the number of bits needed to shift the Sk64 to the right - in order to make it fit in a signed 32 bit integer. - */ - int shiftToMake32() const; - - /** Set the number to zero */ - void setZero() { fHi = fLo = 0; } - - /** Set the high and low 32 bit values of the number */ - void set(int32_t hi, uint32_t lo) { fHi = hi; fLo = lo; } - - /** Set the number to the specified 32 bit integer */ - void set(int32_t a) { fHi = a >> 31; fLo = a; } - - /** Set the number to the product of the two 32 bit integers */ - void setMul(int32_t a, int32_t b); - - /** extract 32bits after shifting right by bitCount. - Note: itCount must be [0..63]. - Asserts that no significant high bits were lost. - */ - int32_t getShiftRight(unsigned bitCount) const; - - /** Shift the number left by the specified number of bits. - @param bits How far to shift left, must be [0..63] - */ - void shiftLeft(unsigned bits); - - /** Shift the number right by the specified number of bits. - @param bits How far to shift right, must be [0..63]. This - performs an arithmetic right-shift (sign extending). - */ - void shiftRight(unsigned bits); - - /** Shift the number right by the specified number of bits, but - round the result. - @param bits How far to shift right, must be [0..63]. This - performs an arithmetic right-shift (sign extending). - */ - void roundRight(unsigned bits); - - /** Add the specified 32 bit integer to the number */ - void add(int32_t lo) { - int32_t hi = lo >> 31; // 0 or -1 - uint32_t sum = fLo + (uint32_t)lo; - - fHi = fHi + hi + (sum < fLo); - fLo = sum; - } - - /** Add the specified Sk64 to the number */ - void add(int32_t hi, uint32_t lo) { - uint32_t sum = fLo + lo; - - fHi = fHi + hi + (sum < fLo); - fLo = sum; - } - - /** Add the specified Sk64 to the number */ - void add(const Sk64& other) { this->add(other.fHi, other.fLo); } - - /** Subtract the specified Sk64 from the number. (*this) = (*this) - num - */ - void sub(const Sk64& num); - - /** Subtract the number from the specified Sk64. (*this) = num - (*this) - */ - void rsub(const Sk64& num); - - /** Multiply the number by the specified 32 bit integer - */ - void mul(int32_t); - - enum DivOptions { - kTrunc_DivOption, //!< truncate the result when calling div() - kRound_DivOption //!< round the result when calling div() - }; - - /** Divide the number by the specified 32 bit integer, using the specified - divide option (either truncate or round). - */ - void div(int32_t, DivOptions); - - friend bool operator==(const Sk64& a, const Sk64& b) { - return a.fHi == b.fHi && a.fLo == b.fLo; - } - - friend bool operator!=(const Sk64& a, const Sk64& b) { - return a.fHi != b.fHi || a.fLo != b.fLo; - } - - friend bool operator<(const Sk64& a, const Sk64& b) { - return a.fHi < b.fHi || (a.fHi == b.fHi && a.fLo < b.fLo); - } - - friend bool operator<=(const Sk64& a, const Sk64& b) { - return a.fHi < b.fHi || (a.fHi == b.fHi && a.fLo <= b.fLo); - } - - friend bool operator>(const Sk64& a, const Sk64& b) { - return a.fHi > b.fHi || (a.fHi == b.fHi && a.fLo > b.fLo); - } - - friend bool operator>=(const Sk64& a, const Sk64& b) { - return a.fHi > b.fHi || (a.fHi == b.fHi && a.fLo >= b.fLo); - } - - // Private to unittests. Parameter is (skiatest::Reporter*) - static void UnitTestWithReporter(void* skiatest_reporter); -}; - -#endif diff --git a/libskia/include/core/SkAdvancedTypefaceMetrics.h b/libskia/include/core/SkAdvancedTypefaceMetrics.h deleted file mode 100755 index e75365ba..00000000 --- a/libskia/include/core/SkAdvancedTypefaceMetrics.h +++ /dev/null @@ -1,156 +0,0 @@ - -/* - * Copyright 2011 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - - -#ifndef SkAdvancedTypefaceMetrics_DEFINED -#define SkAdvancedTypefaceMetrics_DEFINED - -#include "SkRect.h" -#include "SkRefCnt.h" -#include "SkString.h" -#include "SkTDArray.h" -#include "SkTemplates.h" - -/** \class SkAdvancedTypefaceMetrics - - The SkAdvancedTypefaceMetrics class is used by the PDF backend to correctly - embed typefaces. This class is filled in with information about a given - typeface by the SkFontHost class. -*/ - -class SkAdvancedTypefaceMetrics : public SkRefCnt { -public: - SK_DECLARE_INST_COUNT(SkAdvancedTypefaceMetrics) - - SkString fFontName; - - enum FontType { - kType1_Font, - kType1CID_Font, - kCFF_Font, - kTrueType_Font, - kOther_Font, - kNotEmbeddable_Font - }; - // The type of the underlying font program. This field determines which - // of the following fields are valid. If it is kOther_Font or - // kNotEmbeddable_Font, the per glyph information will never be populated. - FontType fType; - - // fMultiMaster may be true for Type1_Font or CFF_Font. - bool fMultiMaster; - uint16_t fLastGlyphID; // The last valid glyph ID in the font. - uint16_t fEmSize; // The size of the em box (defines font units). - - // These enum values match the values used in the PDF file format. - enum StyleFlags { - kFixedPitch_Style = 0x00001, - kSerif_Style = 0x00002, - kScript_Style = 0x00008, - kItalic_Style = 0x00040, - kAllCaps_Style = 0x10000, - kSmallCaps_Style = 0x20000, - kForceBold_Style = 0x40000 - }; - uint16_t fStyle; // Font style characteristics. - int16_t fItalicAngle; // Counterclockwise degrees from vertical of the - // dominant vertical stroke for an Italic face. - // The following fields are all in font units. - int16_t fAscent; // Max height above baseline, not including accents. - int16_t fDescent; // Max depth below baseline (negative). - int16_t fStemV; // Thickness of dominant vertical stem. - int16_t fCapHeight; // Height (from baseline) of top of flat capitals. - - SkIRect fBBox; // The bounding box of all glyphs (in font units). - - // The type of advance data wanted. - enum PerGlyphInfo { - kNo_PerGlyphInfo = 0x0, // Don't populate any per glyph info. - kHAdvance_PerGlyphInfo = 0x1, // Populate horizontal advance data. - kVAdvance_PerGlyphInfo = 0x2, // Populate vertical advance data. - kGlyphNames_PerGlyphInfo = 0x4, // Populate glyph names (Type 1 only). - kToUnicode_PerGlyphInfo = 0x8 // Populate ToUnicode table, ignored - // for Type 1 fonts - }; - - template - struct AdvanceMetric { - enum MetricType { - kDefault, // Default advance: fAdvance.count = 1 - kRange, // Advances for a range: fAdvance.count = fEndID-fStartID - kRun // fStartID-fEndID have same advance: fAdvance.count = 1 - }; - MetricType fType; - uint16_t fStartId; - uint16_t fEndId; - SkTDArray fAdvance; - SkAutoTDelete > fNext; - }; - - struct VerticalMetric { - int16_t fVerticalAdvance; - int16_t fOriginXDisp; // Horiz. displacement of the secondary origin. - int16_t fOriginYDisp; // Vert. displacement of the secondary origin. - }; - typedef AdvanceMetric WidthRange; - typedef AdvanceMetric VerticalAdvanceRange; - - // This is indexed by glyph id. - SkAutoTDelete fGlyphWidths; - // Only used for Vertical CID fonts. - SkAutoTDelete fVerticalMetrics; - - // The names of each glyph, only populated for postscript fonts. - SkAutoTDelete > fGlyphNames; - - // The mapping from glyph to Unicode, only populated if - // kToUnicode_PerGlyphInfo is passed to GetAdvancedTypefaceMetrics. - SkTDArray fGlyphToUnicode; - -private: - typedef SkRefCnt INHERITED; -}; - -namespace skia_advanced_typeface_metrics_utils { - -template -void resetRange(SkAdvancedTypefaceMetrics::AdvanceMetric* range, - int startId); - -template -SkAdvancedTypefaceMetrics::AdvanceMetric* appendRange( - SkAutoTDelete >* nextSlot, - int startId); - -template -void finishRange( - SkAdvancedTypefaceMetrics::AdvanceMetric* range, - int endId, - typename SkAdvancedTypefaceMetrics::AdvanceMetric::MetricType - type); - -/** Retrieve advance data for glyphs. Used by the PDF backend. It calls - underlying platform dependent API getAdvance to acquire the data. - @param num_glyphs Total number of glyphs in the given font. - @param glyphIDs For per-glyph info, specify subset of the font by - giving glyph ids. Each integer represents a glyph - id. Passing NULL means all glyphs in the font. - @param glyphIDsCount Number of elements in subsetGlyphIds. Ignored if - glyphIDs is NULL. -*/ -template -SkAdvancedTypefaceMetrics::AdvanceMetric* getAdvanceData( - FontHandle fontHandle, - int num_glyphs, - const uint32_t* glyphIDs, - uint32_t glyphIDsCount, - bool (*getAdvance)(FontHandle fontHandle, int gId, Data* data)); - -} // namespace skia_advanced_typeface_metrics_utils - -#endif diff --git a/libskia/include/core/SkAnnotation.h b/libskia/include/core/SkAnnotation.h index 4d17b790..35cc2b5d 100644 --- a/libskia/include/core/SkAnnotation.h +++ b/libskia/include/core/SkAnnotation.h @@ -8,77 +8,18 @@ #ifndef SkAnnotation_DEFINED #define SkAnnotation_DEFINED -#include "SkRefCnt.h" -#include "SkString.h" +#include "SkTypes.h" class SkData; -class SkFlattenableReadBuffer; -class SkFlattenableWriteBuffer; -class SkStream; -class SkWStream; struct SkPoint; - -/** - * Experimental class for annotating draws. Do not use directly yet. - * Use helper functions at the bottom of this file for now. - */ -class SkAnnotation : public SkRefCnt { -public: - SkAnnotation(const char key[], SkData* value); - virtual ~SkAnnotation(); - - /** - * Return the data for the specified key, or NULL. - */ - SkData* find(const char key[]) const; - - SkAnnotation(SkFlattenableReadBuffer&); - void writeToBuffer(SkFlattenableWriteBuffer&) const; - -private: - SkString fKey; - SkData* fData; - - typedef SkRefCnt INHERITED; -}; - -/** - * Experimental collection of predefined Keys into the Annotation dictionary - */ -class SkAnnotationKeys { -public: - /** - * Returns the canonical key whose payload is a URL - */ - static const char* URL_Key(); - - /** - * Returns the canonical key whose payload is the name of a destination to - * be defined. - */ - static const char* Define_Named_Dest_Key(); - - /** - * Returns the canonical key whose payload is the name of a destination to - * be linked to. - */ - static const char* Link_Named_Dest_Key(); -}; - -/////////////////////////////////////////////////////////////////////////////// -// -// Experimental helper functions to use Annotations -// - struct SkRect; class SkCanvas; /** - * Experimental! - * * Annotate the canvas by associating the specified URL with the - * specified rectangle (in local coordinates, just like drawRect). If the - * backend of this canvas does not support annotations, this call is + * specified rectangle (in local coordinates, just like drawRect). + * + * If the backend of this canvas does not support annotations, this call is * safely ignored. * * The caller is responsible for managing its ownership of the SkData. @@ -86,8 +27,6 @@ class SkCanvas; SK_API void SkAnnotateRectWithURL(SkCanvas*, const SkRect&, SkData*); /** - * Experimental! - * * Annotate the canvas by associating a name with the specified point. * * If the backend of this canvas does not support annotations, this call is @@ -98,8 +37,6 @@ SK_API void SkAnnotateRectWithURL(SkCanvas*, const SkRect&, SkData*); SK_API void SkAnnotateNamedDestination(SkCanvas*, const SkPoint&, SkData*); /** - * Experimental! - * * Annotate the canvas by making the specified rectangle link to a named * destination. * @@ -110,5 +47,4 @@ SK_API void SkAnnotateNamedDestination(SkCanvas*, const SkPoint&, SkData*); */ SK_API void SkAnnotateLinkToDestination(SkCanvas*, const SkRect&, SkData*); - #endif diff --git a/libskia/include/core/SkBBHFactory.h b/libskia/include/core/SkBBHFactory.h new file mode 100644 index 00000000..58bd754b --- /dev/null +++ b/libskia/include/core/SkBBHFactory.h @@ -0,0 +1,31 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkBBHFactory_DEFINED +#define SkBBHFactory_DEFINED + +#include "SkTypes.h" +class SkBBoxHierarchy; +struct SkRect; + +class SK_API SkBBHFactory { +public: + /** + * Allocate a new SkBBoxHierarchy. Return NULL on failure. + */ + virtual SkBBoxHierarchy* operator()(const SkRect& bounds) const = 0; + virtual ~SkBBHFactory() {} +}; + +class SK_API SkRTreeFactory : public SkBBHFactory { +public: + SkBBoxHierarchy* operator()(const SkRect& bounds) const override; +private: + typedef SkBBHFactory INHERITED; +}; + +#endif diff --git a/libskia/include/core/SkBitmap.h b/libskia/include/core/SkBitmap.h index 2b900bef..061f0e5c 100644 --- a/libskia/include/core/SkBitmap.h +++ b/libskia/include/core/SkBitmap.h @@ -11,26 +11,23 @@ #include "SkColor.h" #include "SkColorTable.h" #include "SkImageInfo.h" +#include "SkPixmap.h" #include "SkPoint.h" #include "SkRefCnt.h" -#ifdef SK_SUPPORT_LEGACY_SK64 - #include "Sk64.h" -#endif - +struct SkMask; struct SkIRect; struct SkRect; class SkPaint; class SkPixelRef; +class SkPixelRefFactory; class SkRegion; class SkString; -class GrTexture; - /** \class SkBitmap The SkBitmap class specifies a raster bitmap. A bitmap has an integer width - and height, and a format (config), and a pointer to the actual pixels. + and height, and a format (colortype), and a pointer to the actual pixels. Bitmaps can be drawn into a SkCanvas, but they are also used to specify the target of a SkCanvas' drawing operations. A const SkBitmap exposes getAddr(), which lets a caller write its pixels; @@ -41,24 +38,9 @@ class SK_API SkBitmap { public: class SK_API Allocator; - enum Config { - kNo_Config, //!< bitmap has not been configured - kA8_Config, //!< 8-bits per pixel, with only alpha specified (0 is transparent, 0xFF is opaque) - kIndex8_Config, //!< 8-bits per pixel, using SkColorTable to specify the colors - kRGB_565_Config, //!< 16-bits per pixel, (see SkColorPriv.h for packing) - kARGB_4444_Config, //!< 16-bits per pixel, (see SkColorPriv.h for packing) - kARGB_8888_Config, //!< 32-bits per pixel, (see SkColorPriv.h for packing) - }; - - // do not add this to the Config enum, otherwise the compiler will let us - // pass this as a valid parameter for Config. - enum { - kConfigCount = kARGB_8888_Config + 1 - }; - /** * Default construct creates a bitmap with zero width and height, and no pixels. - * Its config is set to kNo_Config. + * Its colortype is set to kUnknown_SkColorType. */ SkBitmap(); @@ -71,66 +53,87 @@ class SK_API SkBitmap { */ SkBitmap(const SkBitmap& src); + /** + * Copy the settings from the src into this bitmap. If the src has pixels + * allocated, ownership of the pixels will be taken. + */ + SkBitmap(SkBitmap&& src); + ~SkBitmap(); - /** Copies the src bitmap into this bitmap. Ownership of the src bitmap's pixels remains - with the src bitmap. + /** Copies the src bitmap into this bitmap. Ownership of the src + bitmap's pixels is shared with the src bitmap. */ SkBitmap& operator=(const SkBitmap& src); + + /** Copies the src bitmap into this bitmap. Takes ownership of the src + bitmap's pixels. + */ + SkBitmap& operator=(SkBitmap&& src); + /** Swap the fields of the two bitmaps. This routine is guaranteed to never fail or throw. */ // This method is not exported to java. void swap(SkBitmap& other); - /** Return true iff the bitmap has empty dimensions. - */ - bool empty() const { return 0 == fWidth || 0 == fHeight; } + /////////////////////////////////////////////////////////////////////////// - /** Return true iff the bitmap has no pixelref. Note: this can return true even if the - dimensions of the bitmap are > 0 (see empty()). - */ - bool isNull() const { return NULL == fPixelRef; } + const SkImageInfo& info() const { return fInfo; } - /** Return the config for the bitmap. */ - Config config() const { return (Config)fConfig; } + int width() const { return fInfo.width(); } + int height() const { return fInfo.height(); } + SkColorType colorType() const { return fInfo.colorType(); } + SkAlphaType alphaType() const { return fInfo.alphaType(); } + SkColorSpace* colorSpace() const { return fInfo.colorSpace(); } - SK_ATTR_DEPRECATED("use config()") - Config getConfig() const { return this->config(); } + /** + * Return the number of bytes per pixel based on the colortype. If the colortype is + * kUnknown_SkColorType, then 0 is returned. + */ + int bytesPerPixel() const { return fInfo.bytesPerPixel(); } - /** Return the bitmap's width, in pixels. */ - int width() const { return fWidth; } + /** + * Return the rowbytes expressed as a number of pixels (like width and height). + * If the colortype is kUnknown_SkColorType, then 0 is returned. + */ + int rowBytesAsPixels() const { + return fRowBytes >> this->shiftPerPixel(); + } - /** Return the bitmap's height, in pixels. */ - int height() const { return fHeight; } + /** + * Return the shift amount per pixel (i.e. 0 for 1-byte per pixel, 1 for 2-bytes per pixel + * colortypes, 2 for 4-bytes per pixel colortypes). Return 0 for kUnknown_SkColorType. + */ + int shiftPerPixel() const { return this->fInfo.shiftPerPixel(); } - /** Return the number of bytes between subsequent rows of the bitmap. */ - size_t rowBytes() const { return fRowBytes; } + /////////////////////////////////////////////////////////////////////////// - /** Return the shift amount per pixel (i.e. 0 for 1-byte per pixel, 1 for - 2-bytes per pixel configs, 2 for 4-bytes per pixel configs). Return 0 - for configs that are not at least 1-byte per pixel (e.g. kA1_Config - or kNo_Config) - */ - int shiftPerPixel() const { return fBytesPerPixel >> 1; } + /** Return true iff the bitmap has empty dimensions. + * Hey! Before you use this, see if you really want to know drawsNothing() instead. + */ + bool empty() const { return fInfo.isEmpty(); } - /** Return the number of bytes per pixel based on the config. If the config - does not have at least 1 byte per (e.g. kA1_Config) then 0 is returned. - */ - int bytesPerPixel() const { return fBytesPerPixel; } + /** Return true iff the bitmap has no pixelref. Note: this can return true even if the + * dimensions of the bitmap are > 0 (see empty()). + * Hey! Before you use this, see if you really want to know drawsNothing() instead. + */ + bool isNull() const { return NULL == fPixelRef; } - /** Return the rowbytes expressed as a number of pixels (like width and - height). Note, for 1-byte per pixel configs like kA8_Config, this will - return the same as rowBytes(). Is undefined for configs that are less - than 1-byte per pixel (e.g. kA1_Config) - */ - int rowBytesAsPixels() const { return fRowBytes >> (fBytesPerPixel >> 1); } + /** Return true iff drawing this bitmap has no effect. + */ + bool drawsNothing() const { return this->empty() || this->isNull(); } - SkAlphaType alphaType() const { return (SkAlphaType)fAlphaType; } + /** Return the number of bytes between subsequent rows of the bitmap. */ + size_t rowBytes() const { return fRowBytes; } /** * Set the bitmap's alphaType, returning true on success. If false is * returned, then the specified new alphaType is incompatible with the - * Config, and the current alphaType is unchanged. + * colortype, and the current alphaType is unchanged. + * + * Note: this changes the alphatype for the underlying pixels, which means + * that all bitmaps that might be sharing (subsets of) the pixels will + * be affected. */ bool setAlphaType(SkAlphaType); @@ -142,19 +145,19 @@ class SK_API SkBitmap { Note this truncates the result to 32bits. Call getSize64() to detect if the real size exceeds 32bits. */ - size_t getSize() const { return fHeight * fRowBytes; } + size_t getSize() const { return fInfo.height() * fRowBytes; } /** Return the number of bytes from the pointer returned by getPixels() to the end of the allocated space in the buffer. Required in cases where extractSubset has been called. */ - size_t getSafeSize() const ; + size_t getSafeSize() const { return fInfo.getSafeSize(fRowBytes); } /** * Return the full size of the bitmap, in bytes. */ int64_t computeSize64() const { - return sk_64_mul(fHeight, fRowBytes); + return sk_64_mul(fInfo.height(), fRowBytes); } /** @@ -163,25 +166,9 @@ class SK_API SkBitmap { * than computeSize64() if there is any rowbytes padding beyond the width. */ int64_t computeSafeSize64() const { - return ComputeSafeSize64((Config)fConfig, fWidth, fHeight, fRowBytes); + return fInfo.getSafeSize64(fRowBytes); } -#ifdef SK_SUPPORT_LEGACY_SK64 - SK_ATTR_DEPRECATED("use getSize64()") - Sk64 getSize64() const { - Sk64 size; - size.set64(this->computeSize64()); - return size; - } - - SK_ATTR_DEPRECATED("use getSafeSize64()") - Sk64 getSafeSize64() const { - Sk64 size; - size.set64(this->computeSafeSize64()); - return size; - } -#endif - /** Returns true if this bitmap is marked as immutable, meaning that the contents of its pixels will not change for the lifetime of the bitmap. */ @@ -219,26 +206,6 @@ class SK_API SkBitmap { */ void reset(); - /** Given a config and a width, this computes the optimal rowBytes value. This is called automatically - if you pass 0 for rowBytes to setConfig(). - */ - static size_t ComputeRowBytes(Config c, int width); - - /** Return the bytes-per-pixel for the specified config. If the config is - not at least 1-byte per pixel, return 0, including for kNo_Config. - */ - static int ComputeBytesPerPixel(Config c); - - /** Return the shift-per-pixel for the specified config. If the config is - not at least 1-byte per pixel, return 0, including for kNo_Config. - */ - static int ComputeShiftPerPixel(Config c) { - return ComputeBytesPerPixel(c) >> 1; - } - - static int64_t ComputeSize64(Config, int width, int height); - static size_t ComputeSize(Config, int width, int height); - /** * This will brute-force return true if all of the pixels in the bitmap * are opaque. If it fails to read the pixels, or encounters an error, @@ -256,25 +223,102 @@ class SK_API SkBitmap { void getBounds(SkRect* bounds) const; void getBounds(SkIRect* bounds) const; - /** Set the bitmap's config and dimensions. If rowBytes is 0, then - ComputeRowBytes() is called to compute the optimal value. This resets - any pixel/colortable ownership, just like reset(). - */ - bool setConfig(Config, int width, int height, size_t rowBytes, SkAlphaType); + SkIRect bounds() const { return fInfo.bounds(); } + SkISize dimensions() const { return fInfo.dimensions(); } + // Returns the bounds of this bitmap, offset by its pixelref origin. + SkIRect getSubset() const { + return SkIRect::MakeXYWH(fPixelRefOrigin.x(), fPixelRefOrigin.y(), + fInfo.width(), fInfo.height()); + } + + bool setInfo(const SkImageInfo&, size_t rowBytes = 0); + + /** + * Allocate the bitmap's pixels to match the requested image info. If the Factory + * is non-null, call it to allcoate the pixelref. If the ImageInfo requires + * a colortable, then ColorTable must be non-null, and will be ref'd. + * On failure, the bitmap will be set to empty and return false. + */ + bool SK_WARN_UNUSED_RESULT tryAllocPixels(const SkImageInfo&, SkPixelRefFactory*, SkColorTable*); + + void allocPixels(const SkImageInfo& info, SkPixelRefFactory* factory, SkColorTable* ctable) { + if (!this->tryAllocPixels(info, factory, ctable)) { + sk_throw(); + } + } + + /** + * Allocate the bitmap's pixels to match the requested image info and + * rowBytes. If the request cannot be met (e.g. the info is invalid or + * the requested rowBytes are not compatible with the info + * (e.g. rowBytes < info.minRowBytes() or rowBytes is not aligned with + * the pixel size specified by info.colorType()) then false is returned + * and the bitmap is set to empty. + */ + bool SK_WARN_UNUSED_RESULT tryAllocPixels(const SkImageInfo& info, size_t rowBytes); + + void allocPixels(const SkImageInfo& info, size_t rowBytes) { + if (!this->tryAllocPixels(info, rowBytes)) { + sk_throw(); + } + } + + bool SK_WARN_UNUSED_RESULT tryAllocPixels(const SkImageInfo& info) { + return this->tryAllocPixels(info, info.minRowBytes()); + } + + void allocPixels(const SkImageInfo& info) { + this->allocPixels(info, info.minRowBytes()); + } + + bool SK_WARN_UNUSED_RESULT tryAllocN32Pixels(int width, int height, bool isOpaque = false) { + SkImageInfo info = SkImageInfo::MakeN32(width, height, + isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType); + return this->tryAllocPixels(info); + } - bool setConfig(Config config, int width, int height, size_t rowBytes = 0) { - return this->setConfig(config, width, height, rowBytes, - kPremul_SkAlphaType); + void allocN32Pixels(int width, int height, bool isOpaque = false) { + SkImageInfo info = SkImageInfo::MakeN32(width, height, + isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType); + this->allocPixels(info); } - bool setConfig(const SkImageInfo& info, size_t rowBytes = 0); + /** + * Install a pixelref that wraps the specified pixels and rowBytes, and + * optional ReleaseProc and context. When the pixels are no longer + * referenced, if releaseProc is not null, it will be called with the + * pixels and context as parameters. + * On failure, the bitmap will be set to empty and return false. + * + * If specified, the releaseProc will always be called, even on failure. It is also possible + * for success but the releaseProc is immediately called (e.g. valid Info but NULL pixels). + */ + bool installPixels(const SkImageInfo&, void* pixels, size_t rowBytes, SkColorTable*, + void (*releaseProc)(void* addr, void* context), void* context); + + /** + * Call installPixels with no ReleaseProc specified. This means that the + * caller must ensure that the specified pixels are valid for the lifetime + * of the created bitmap (and its pixelRef). + */ + bool installPixels(const SkImageInfo& info, void* pixels, size_t rowBytes) { + return this->installPixels(info, pixels, rowBytes, NULL, NULL, NULL); + } /** - * If the bitmap's config can be represented as SkImageInfo, return true, - * and if info is not-null, set it to the bitmap's info. If it cannot be - * represented as SkImageInfo, return false and ignore the info parameter. + * Call installPixels with no ReleaseProc specified. This means + * that the caller must ensure that the specified pixels and + * colortable are valid for the lifetime of the created bitmap + * (and its pixelRef). */ - bool asImageInfo(SkImageInfo* info) const; + bool installPixels(const SkPixmap&); + + /** + * Calls installPixels() with the value in the SkMask. The caller must + * ensure that the specified mask pixels are valid for the lifetime + * of the created bitmap (and its pixelRef). + */ + bool installMaskPixels(const SkMask&); /** Use this to assign a new pixel address for an existing bitmap. This will automatically release any pixelref previously installed. Only call @@ -310,7 +354,7 @@ class SK_API SkBitmap { bool preserveDstPad = false) const; /** Use the standard HeapAllocator to create the pixelref that manages the - pixel memory. It will be sized based on the current width/height/config. + pixel memory. It will be sized based on the current ImageInfo. If this is called multiple times, a new pixelref object will be created each time. @@ -318,16 +362,20 @@ class SK_API SkBitmap { not null) it will take care of incrementing the reference count. @param ctable ColorTable (or null) to use with the pixels that will - be allocated. Only used if config == Index8_Config + be allocated. Only used if colortype == kIndex_8_SkColorType @return true if the allocation succeeds. If not the pixelref field of the bitmap will be unchanged. */ - bool allocPixels(SkColorTable* ctable = NULL) { - return this->allocPixels(NULL, ctable); + bool SK_WARN_UNUSED_RESULT tryAllocPixels(SkColorTable* ctable = NULL) { + return this->tryAllocPixels(NULL, ctable); + } + + void allocPixels(SkColorTable* ctable = NULL) { + this->allocPixels(NULL, ctable); } /** Use the specified Allocator to create the pixelref that manages the - pixel memory. It will be sized based on the current width/height/config. + pixel memory. It will be sized based on the current ImageInfo. If this is called multiple times, a new pixelref object will be created each time. @@ -335,30 +383,58 @@ class SK_API SkBitmap { not null) it will take care of incrementing the reference count. @param allocator The Allocator to use to create a pixelref that can - manage the pixel memory for the current - width/height/config. If allocator is NULL, the standard - HeapAllocator will be used. + manage the pixel memory for the current ImageInfo. + If allocator is NULL, the standard HeapAllocator will be used. @param ctable ColorTable (or null) to use with the pixels that will - be allocated. Only used if config == Index8_Config. - If it is non-null and the config is not Index8, it will + be allocated. Only used if colortype == kIndex_8_SkColorType. + If it is non-null and the colortype is not indexed, it will be ignored. @return true if the allocation succeeds. If not the pixelref field of the bitmap will be unchanged. */ - bool allocPixels(Allocator* allocator, SkColorTable* ctable); + bool SK_WARN_UNUSED_RESULT tryAllocPixels(Allocator* allocator, SkColorTable* ctable); - /** Return the current pixelref object, if any - */ + void allocPixels(Allocator* allocator, SkColorTable* ctable) { + if (!this->tryAllocPixels(allocator, ctable)) { + sk_throw(); + } + } + + /** + * Return the current pixelref object or NULL if there is none. This does + * not affect the refcount of the pixelref. + */ SkPixelRef* pixelRef() const { return fPixelRef; } - /** Return the offset into the pixelref, if any. Will return 0 if there is - no pixelref installed. - */ - size_t pixelRefOffset() const { return fPixelRefOffset; } - /** Assign a pixelref and optional offset. Pixelrefs are reference counted, - so the existing one (if any) will be unref'd and the new one will be - ref'd. - */ - SkPixelRef* setPixelRef(SkPixelRef* pr, size_t offset = 0); + + /** + * A bitmap can reference a subset of a pixelref's pixels. That means the + * bitmap's width/height can be <= the dimensions of the pixelref. The + * pixelref origin is the x,y location within the pixelref's pixels for + * the bitmap's top/left corner. To be valid the following must be true: + * + * origin_x + bitmap_width <= pixelref_width + * origin_y + bitmap_height <= pixelref_height + * + * pixelRefOrigin() returns this origin, or (0,0) if there is no pixelRef. + */ + SkIPoint pixelRefOrigin() const { return fPixelRefOrigin; } + + /** + * Assign a pixelref and origin to the bitmap. Pixelrefs are reference, + * so the existing one (if any) will be unref'd and the new one will be + * ref'd. (x,y) specify the offset within the pixelref's pixels for the + * top/left corner of the bitmap. For a bitmap that encompases the entire + * pixels of the pixelref, these will be (0,0). + */ + SkPixelRef* setPixelRef(SkPixelRef* pr, int dx, int dy); + + SkPixelRef* setPixelRef(SkPixelRef* pr, const SkIPoint& origin) { + return this->setPixelRef(pr, origin.fX, origin.fY); + } + + SkPixelRef* setPixelRef(SkPixelRef* pr) { + return this->setPixelRef(pr, 0, 0); + } /** Call this to ensure that the bitmap points to the current pixel address in the pixelref. Balance it with a call to unlockPixels(). These calls @@ -378,23 +454,22 @@ class SK_API SkBitmap { * not be used as targets for a raster device/canvas (since all pixels * modifications will be lost when unlockPixels() is called.) */ + // DEPRECATED bool lockPixelsAreWritable() const; + bool requestLock(SkAutoPixmapUnlock* result) const; + /** Call this to be sure that the bitmap is valid enough to be drawn (i.e. - it has non-null pixels, and if required by its config, it has a + it has non-null pixels, and if required by its colortype, it has a non-null colortable. Returns true if all of the above are met. */ bool readyToDraw() const { return this->getPixels() != NULL && - (this->config() != kIndex8_Config || NULL != fColorTable); + (this->colorType() != kIndex_8_SkColorType || fColorTable); } - /** Returns the pixelRef's texture, or NULL - */ - GrTexture* getTexture() const; - - /** Return the bitmap's colortable, if it uses one (i.e. fConfig is - kIndex8_Config) and the pixels are locked. + /** Return the bitmap's colortable, if it uses one (i.e. colorType is + Index_8) and the pixels are locked. Otherwise returns NULL. Does not affect the colortable's reference count. */ @@ -403,7 +478,7 @@ class SK_API SkBitmap { /** Returns a non-zero, unique value corresponding to the pixels in our pixelref. Each time the pixels are changed (and notifyPixelsChanged is called), a different generation ID will be returned. Finally, if - their is no pixelRef then zero is returned. + there is no pixelRef then zero is returned. */ uint32_t getGenerationID() const; @@ -415,22 +490,21 @@ class SK_API SkBitmap { /** * Fill the entire bitmap with the specified color. - * If the bitmap's config does not support alpha (e.g. 565) then the alpha - * of the color is ignored (treated as opaque). If the config only supports + * If the bitmap's colortype does not support alpha (e.g. 565) then the alpha + * of the color is ignored (treated as opaque). If the colortype only supports * alpha (e.g. A1 or A8) then the color's r,g,b components are ignored. */ - void eraseColor(SkColor c) const { - this->eraseARGB(SkColorGetA(c), SkColorGetR(c), SkColorGetG(c), - SkColorGetB(c)); - } + void eraseColor(SkColor c) const; /** * Fill the entire bitmap with the specified color. - * If the bitmap's config does not support alpha (e.g. 565) then the alpha - * of the color is ignored (treated as opaque). If the config only supports + * If the bitmap's colortype does not support alpha (e.g. 565) then the alpha + * of the color is ignored (treated as opaque). If the colortype only supports * alpha (e.g. A1 or A8) then the color's r,g,b components are ignored. */ - void eraseARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) const; + void eraseARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) const { + this->eraseColor(SkColorSetARGB(a, r, g, b)); + } SK_ATTR_DEPRECATED("use eraseARGB or eraseColor") void eraseRGB(U8CPU r, U8CPU g, U8CPU b) const { @@ -439,43 +513,31 @@ class SK_API SkBitmap { /** * Fill the specified area of this bitmap with the specified color. - * If the bitmap's config does not support alpha (e.g. 565) then the alpha - * of the color is ignored (treated as opaque). If the config only supports + * If the bitmap's colortype does not support alpha (e.g. 565) then the alpha + * of the color is ignored (treated as opaque). If the colortype only supports * alpha (e.g. A1 or A8) then the color's r,g,b components are ignored. */ - void eraseArea(const SkIRect& area, SkColor c) const; - - /** Scroll (a subset of) the contents of this bitmap by dx/dy. If there are - no pixels allocated (i.e. getPixels() returns null) the method will - still update the inval region (if present). If the bitmap is immutable, - do nothing and return false. - - @param subset The subset of the bitmap to scroll/move. To scroll the - entire contents, specify [0, 0, width, height] or just - pass null. - @param dx The amount to scroll in X - @param dy The amount to scroll in Y - @param inval Optional (may be null). Returns the area of the bitmap that - was scrolled away. E.g. if dx = dy = 0, then inval would - be set to empty. If dx >= width or dy >= height, then - inval would be set to the entire bounds of the bitmap. - @return true if the scroll was doable. Will return false if the bitmap - uses an unsupported config for scrolling (only kA8, - kIndex8, kRGB_565, kARGB_4444, kARGB_8888 are supported). - If no pixels are present (i.e. getPixels() returns false) - inval will still be updated, and true will be returned. - */ - bool scrollRect(const SkIRect* subset, int dx, int dy, - SkRegion* inval = NULL) const; + void erase(SkColor c, const SkIRect& area) const; + + // DEPRECATED + void eraseArea(const SkIRect& area, SkColor c) const { + this->erase(c, area); + } /** - * Return the SkColor of the specified pixel. In most cases this will - * require un-premultiplying the color. Alpha only configs (A1 and A8) - * return black with the appropriate alpha set. The value is undefined - * for kNone_Config or if x or y are out of bounds, or if the bitmap - * does not have any pixels (or has not be locked with lockPixels()). + * Converts the pixel at the specified coordinate to an unpremultiplied + * SkColor. Note: this ignores any SkColorSpace information, and may return + * lower precision data than is actually in the pixel. Alpha only + * colortypes (e.g. kAlpha_8_SkColorType) return black with the appropriate + * alpha set. The value is undefined for kUnknown_SkColorType or if x or y + * are out of bounds, or if the bitmap does not have any pixels (or has not + * be locked with lockPixels()).. */ - SkColor getColor(int x, int y) const; + SkColor getColor(int x, int y) const { + SkPixmap pixmap; + SkAssertResult(this->peekPixels(&pixmap)); + return pixmap.getColor(x, y); + } /** Returns the address of the specified pixel. This performs a runtime check to know the size of the pixels, and will return the same answer @@ -490,21 +552,21 @@ class SK_API SkBitmap { /** Returns the address of the pixel specified by x,y for 32bit pixels. * In debug build, this asserts that the pixels are allocated and locked, - * and that the config is 32-bit, however none of these checks are performed + * and that the colortype is 32-bit, however none of these checks are performed * in the release build. */ inline uint32_t* getAddr32(int x, int y) const; /** Returns the address of the pixel specified by x,y for 16bit pixels. * In debug build, this asserts that the pixels are allocated and locked, - * and that the config is 16-bit, however none of these checks are performed + * and that the colortype is 16-bit, however none of these checks are performed * in the release build. */ inline uint16_t* getAddr16(int x, int y) const; /** Returns the address of the pixel specified by x,y for 8bit pixels. * In debug build, this asserts that the pixels are allocated and locked, - * and that the config is 8-bit, however none of these checks are performed + * and that the colortype is 8-bit, however none of these checks are performed * in the release build. */ inline uint8_t* getAddr8(int x, int y) const; @@ -512,16 +574,16 @@ class SK_API SkBitmap { /** Returns the color corresponding to the pixel specified by x,y for * colortable based bitmaps. * In debug build, this asserts that the pixels are allocated and locked, - * that the config is kIndex8, and that the colortable is allocated, + * that the colortype is indexed, and that the colortable is allocated, * however none of these checks are performed in the release build. */ inline SkPMColor getIndex8Color(int x, int y) const; /** Set dst to be a setset of this bitmap. If possible, it will share the - pixel memory, and just point into a subset of it. However, if the config + pixel memory, and just point into a subset of it. However, if the colortype does not support this, a local copy will be made and associated with the dst bitmap. If the subset rectangle, intersected with the bitmap's - dimensions is empty, or if there is an unsupported config, false will be + dimensions is empty, or if there is an unsupported colortype, false will be returned and dst will be untouched. @param dst The bitmap that will be set to a subset of this bitmap @param subset The rectangle of pixels in this bitmap that dst will @@ -530,36 +592,59 @@ class SK_API SkBitmap { */ bool extractSubset(SkBitmap* dst, const SkIRect& subset) const; - /** Makes a deep copy of this bitmap, respecting the requested config, + /** Makes a deep copy of this bitmap, respecting the requested colorType, * and allocating the dst pixels on the cpu. * Returns false if either there is an error (i.e. the src does not have * pixels) or the request cannot be satisfied (e.g. the src has per-pixel - * alpha, and the requested config does not support alpha). + * alpha, and the requested colortype does not support alpha). * @param dst The bitmap to be sized and allocated - * @param c The desired config for dst + * @param ct The desired colorType for dst * @param allocator Allocator used to allocate the pixelref for the dst * bitmap. If this is null, the standard HeapAllocator * will be used. - * @return true if the copy could be made. + * @return true if the copy was made. + */ + bool copyTo(SkBitmap* dst, SkColorType ct, Allocator* = NULL) const; + + bool copyTo(SkBitmap* dst, Allocator* allocator = NULL) const { + return this->copyTo(dst, this->colorType(), allocator); + } + + /** + * Copy the bitmap's pixels into the specified buffer (pixels + rowBytes), + * converting them into the requested format (SkImageInfo). The src pixels are read + * starting at the specified (srcX,srcY) offset, relative to the top-left corner. + * + * The specified ImageInfo and (srcX,srcY) offset specifies a source rectangle + * + * srcR.setXYWH(srcX, srcY, dstInfo.width(), dstInfo.height()); + * + * srcR is intersected with the bounds of the bitmap. If this intersection is not empty, + * then we have two sets of pixels (of equal size). Replace the dst pixels with the + * corresponding src pixels, performing any colortype/alphatype transformations needed + * (in the case where the src and dst have different colortypes or alphatypes). + * + * This call can fail, returning false, for several reasons: + * - If srcR does not intersect the bitmap bounds. + * - If the requested colortype/alphatype cannot be converted from the src's types. + * - If the src pixels are not available. + */ + bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes, + int srcX, int srcY) const; + + /** + * Returns true if this bitmap's pixels can be converted into the requested + * colorType, such that copyTo() could succeed. */ - bool copyTo(SkBitmap* dst, Config c, Allocator* allocator = NULL) const; + bool canCopyTo(SkColorType colorType) const; - /** Makes a deep copy of this bitmap, respecting the requested config, and - * with custom allocation logic that will keep the copied pixels + /** Makes a deep copy of this bitmap, keeping the copied pixels * in the same domain as the source: If the src pixels are allocated for * the cpu, then so will the dst. If the src pixels are allocated on the * gpu (typically as a texture), the it will do the same for the dst. * If the request cannot be fulfilled, returns false and dst is unmodified. */ - bool deepCopyTo(SkBitmap* dst, Config c) const; - - /** Returns true if this bitmap can be deep copied into the requested config - by calling copyTo(). - */ - bool canCopyTo(Config newConfig) const; - - SK_ATTR_DEPRECATED("use setFilterLevel on SkPaint") - void buildMipMap(bool forceRebuild = false); + bool deepCopyTo(SkBitmap* dst) const; #ifdef SK_BUILD_FOR_ANDROID bool hasHardwareMipMap() const { @@ -600,26 +685,25 @@ class SK_API SkBitmap { bool extractAlpha(SkBitmap* dst, const SkPaint* paint, Allocator* allocator, SkIPoint* offset) const; - /** The following two functions provide the means to both flatten and - unflatten the bitmap AND its pixels into the provided buffer. - It is recommended that you do not call these functions directly, - but instead call the write/readBitmap functions on the respective - buffers as they can optimize the recording process and avoid recording - duplicate bitmaps and pixelRefs. + /** + * If the pixels are available from this bitmap (w/o locking) return true, and fill out the + * specified pixmap (if not null). If the pixels are not available (either because there are + * none, or becuase accessing them would require locking or other machinary) return false and + * ignore the pixmap parameter. + * + * Note: if this returns true, the results (in the pixmap) are only valid until the bitmap + * is changed in anyway, in which case the results are invalid. */ - void flatten(SkFlattenableWriteBuffer&) const; - void unflatten(SkFlattenableReadBuffer&); + bool peekPixels(SkPixmap*) const; SkDEBUGCODE(void validate() const;) class Allocator : public SkRefCnt { public: - SK_DECLARE_INST_COUNT(Allocator) - /** Allocate the pixel memory for the bitmap, given its dimensions and - config. Return true on success, where success means either setPixels + colortype. Return true on success, where success means either setPixels or setPixelRef was called. The pixels need not be locked when this - returns. If the config requires a colortable, it also must be + returns. If the colortype requires a colortable, it also must be installed via setColorTable. If false is returned, the bitmap and colortable should be left unchanged. */ @@ -634,7 +718,7 @@ class SK_API SkBitmap { */ class HeapAllocator : public Allocator { public: - virtual bool allocPixelRef(SkBitmap*, SkColorTable*); + bool allocPixelRef(SkBitmap*, SkColorTable*) override; }; class RLEPixels { @@ -658,24 +742,19 @@ class SK_API SkBitmap { int fHeight; }; - SkDEVCODE(void toString(SkString* str) const;) + SK_TO_STRING_NONVIRT() private: - struct MipMap; - mutable MipMap* fMipMap; - mutable SkPixelRef* fPixelRef; - mutable size_t fPixelRefOffset; mutable int fPixelLockCount; - // either user-specified (in which case it is not treated as mutable) - // or a cache of the returned value from fPixelRef->lockPixels() + // These are just caches from the locked pixelref mutable void* fPixels; mutable SkColorTable* fColorTable; // only meaningful for kIndex8 + SkIPoint fPixelRefOrigin; + enum Flags { - kImageIsOpaque_Flag = 0x01, kImageIsVolatile_Flag = 0x02, - kImageIsImmutable_Flag = 0x04, #ifdef SK_BUILD_FOR_ANDROID /* A hint for the renderer responsible for drawing this bitmap * indicating that it should attempt to use mipmaps when this bitmap @@ -685,46 +764,24 @@ class SK_API SkBitmap { #endif }; + SkImageInfo fInfo; uint32_t fRowBytes; - uint32_t fWidth; - uint32_t fHeight; - uint8_t fConfig; - uint8_t fAlphaType; uint8_t fFlags; - uint8_t fBytesPerPixel; // based on config - - void internalErase(const SkIRect&, U8CPU a, U8CPU r, U8CPU g, U8CPU b)const; - - /* Internal computations for safe size. - */ - static int64_t ComputeSafeSize64(Config config, - uint32_t width, - uint32_t height, - size_t rowBytes); - static size_t ComputeSafeSize(Config config, - uint32_t width, - uint32_t height, - size_t rowBytes); /* Unreference any pixelrefs or colortables */ void freePixels(); void updatePixelsFromRef() const; - static SkFixed ComputeMipLevel(SkFixed sx, SkFixed dy); - - /** Given scale factors sx, sy, determine the miplevel available in the - bitmap, and return it (this is the amount to shift matrix iterators - by). If dst is not null, it is set to the correct level. - */ - int extractMipLevel(SkBitmap* dst, SkFixed sx, SkFixed sy); - bool hasMipMap() const; - void freeMipMap(); + static void WriteRawPixels(SkWriteBuffer*, const SkBitmap&); + static bool ReadRawPixels(SkReadBuffer*, SkBitmap*); + friend class SkReadBuffer; // unflatten, rawpixels + friend class SkBinaryWriteBuffer; // rawpixels friend struct SkBitmapProcState; }; -class SkAutoLockPixels : public SkNoncopyable { +class SkAutoLockPixels : SkNoncopyable { public: SkAutoLockPixels(const SkBitmap& bm, bool doLock = true) : fBitmap(bm) { fDidLock = doLock; @@ -745,87 +802,33 @@ class SkAutoLockPixels : public SkNoncopyable { //TODO(mtklein): uncomment when 71713004 lands and Chromium's fixed. //#define SkAutoLockPixels(...) SK_REQUIRE_LOCAL_VAR(SkAutoLockPixels) -/** Helper class that performs the lock/unlockColors calls on a colortable. - The destructor will call unlockColors(false) if it has a bitmap's colortable -*/ -class SkAutoLockColors : public SkNoncopyable { -public: - /** Initialize with no bitmap. Call lockColors(bitmap) to lock bitmap's - colortable - */ - SkAutoLockColors() : fCTable(NULL), fColors(NULL) {} - /** Initialize with bitmap, locking its colortable if present - */ - explicit SkAutoLockColors(const SkBitmap& bm) { - fCTable = bm.getColorTable(); - fColors = fCTable ? fCTable->lockColors() : NULL; - } - /** Initialize with a colortable (may be null) - */ - explicit SkAutoLockColors(SkColorTable* ctable) { - fCTable = ctable; - fColors = ctable ? ctable->lockColors() : NULL; - } - ~SkAutoLockColors() { - if (fCTable) { - fCTable->unlockColors(); - } - } - - /** Return the currently locked colors, or NULL if no bitmap's colortable - is currently locked. - */ - const SkPMColor* colors() const { return fColors; } - - /** Locks the table and returns is colors (assuming ctable is not null) and - unlocks the previous table if one was present - */ - const SkPMColor* lockColors(SkColorTable* ctable) { - if (fCTable) { - fCTable->unlockColors(); - } - fCTable = ctable; - fColors = ctable ? ctable->lockColors() : NULL; - return fColors; - } - - const SkPMColor* lockColors(const SkBitmap& bm) { - return this->lockColors(bm.getColorTable()); - } - -private: - SkColorTable* fCTable; - const SkPMColor* fColors; -}; -#define SkAutoLockColors(...) SK_REQUIRE_LOCAL_VAR(SkAutoLockColors) - /////////////////////////////////////////////////////////////////////////////// inline uint32_t* SkBitmap::getAddr32(int x, int y) const { SkASSERT(fPixels); - SkASSERT(fConfig == kARGB_8888_Config); - SkASSERT((unsigned)x < fWidth && (unsigned)y < fHeight); + SkASSERT(4 == this->bytesPerPixel()); + SkASSERT((unsigned)x < (unsigned)this->width() && (unsigned)y < (unsigned)this->height()); return (uint32_t*)((char*)fPixels + y * fRowBytes + (x << 2)); } inline uint16_t* SkBitmap::getAddr16(int x, int y) const { SkASSERT(fPixels); - SkASSERT(fConfig == kRGB_565_Config || fConfig == kARGB_4444_Config); - SkASSERT((unsigned)x < fWidth && (unsigned)y < fHeight); + SkASSERT(2 == this->bytesPerPixel()); + SkASSERT((unsigned)x < (unsigned)this->width() && (unsigned)y < (unsigned)this->height()); return (uint16_t*)((char*)fPixels + y * fRowBytes + (x << 1)); } inline uint8_t* SkBitmap::getAddr8(int x, int y) const { SkASSERT(fPixels); - SkASSERT(fConfig == kA8_Config || fConfig == kIndex8_Config); - SkASSERT((unsigned)x < fWidth && (unsigned)y < fHeight); + SkASSERT(1 == this->bytesPerPixel()); + SkASSERT((unsigned)x < (unsigned)this->width() && (unsigned)y < (unsigned)this->height()); return (uint8_t*)fPixels + y * fRowBytes + x; } inline SkPMColor SkBitmap::getIndex8Color(int x, int y) const { SkASSERT(fPixels); - SkASSERT(fConfig == kIndex8_Config); - SkASSERT((unsigned)x < fWidth && (unsigned)y < fHeight); + SkASSERT(kIndex_8_SkColorType == this->colorType()); + SkASSERT((unsigned)x < (unsigned)this->width() && (unsigned)y < (unsigned)this->height()); SkASSERT(fColorTable); return (*fColorTable)[*((const uint8_t*)fPixels + y * fRowBytes + x)]; } diff --git a/libskia/include/core/SkBitmapDevice.h b/libskia/include/core/SkBitmapDevice.h index 9a6537b3..17cb9847 100644 --- a/libskia/include/core/SkBitmapDevice.h +++ b/libskia/include/core/SkBitmapDevice.h @@ -9,132 +9,71 @@ #ifndef SkBitmapDevice_DEFINED #define SkBitmapDevice_DEFINED +#include "SkBitmap.h" +#include "SkCanvas.h" +#include "SkColor.h" #include "SkDevice.h" +#include "SkImageInfo.h" +#include "SkRect.h" +#include "SkScalar.h" +#include "SkSize.h" +#include "SkSurfaceProps.h" +#include "SkTypes.h" + +class SkDraw; +class SkImageFilterCache; +class SkMatrix; +class SkPaint; +class SkPath; +class SkPixelRef; +class SkPixmap; +class SkRRect; +class SkSurface; +struct SkPoint; /////////////////////////////////////////////////////////////////////////////// class SK_API SkBitmapDevice : public SkBaseDevice { public: - SK_DECLARE_INST_COUNT(SkBitmapDevice) - /** * Construct a new device with the specified bitmap as its backend. It is * valid for the bitmap to have no pixels associated with it. In that case, * any drawing to this device will have no effect. - */ + */ SkBitmapDevice(const SkBitmap& bitmap); /** - * Construct a new device with the specified bitmap as its backend. It is - * valid for the bitmap to have no pixels associated with it. In that case, - * any drawing to this device will have no effect. - */ - SkBitmapDevice(const SkBitmap& bitmap, const SkDeviceProperties& deviceProperties); - - /** - * Create a new raster device and have the pixels be automatically - * allocated. The rowBytes of the device will be computed automatically - * based on the config and the width. - * - * @param config The desired config for the pixels. If the request cannot - * be met, the closest matching support config will be used. - * @param width width (in pixels) of the device - * @param height height (in pixels) of the device - * @param isOpaque Set to true if it is known that all of the pixels will - * be drawn to opaquely. Used as an accelerator when drawing - * these pixels to another device. + * Create a new device along with its requisite pixel memory using + * default SkSurfaceProps (i.e., kLegacyFontHost_InitType-style). + * Note: this entry point is slated for removal - no one should call it. */ - SkBitmapDevice(SkBitmap::Config config, int width, int height, bool isOpaque = false); + static SkBitmapDevice* Create(const SkImageInfo& info); /** - * Create a new raster device and have the pixels be automatically - * allocated. The rowBytes of the device will be computed automatically - * based on the config and the width. - * - * @param config The desired config for the pixels. If the request cannot - * be met, the closest matching support config will be used. - * @param width width (in pixels) of the device - * @param height height (in pixels) of the device - * @param isOpaque Set to true if it is known that all of the pixels will - * be drawn to opaquely. Used as an accelerator when drawing - * these pixels to another device. - * @param deviceProperties Properties which affect compositing. - */ - SkBitmapDevice(SkBitmap::Config config, int width, int height, bool isOpaque, - const SkDeviceProperties& deviceProperties); - - virtual ~SkBitmapDevice(); - - virtual uint32_t getDeviceCapabilities() SK_OVERRIDE { return 0; } - - /** Return the width of the device (in pixels). - */ - virtual int width() const SK_OVERRIDE { return fBitmap.width(); } - /** Return the height of the device (in pixels). - */ - virtual int height() const SK_OVERRIDE { return fBitmap.height(); } - - /** Returns true if the device's bitmap's config treats every pixels as - implicitly opaque. - */ - virtual bool isOpaque() const SK_OVERRIDE { return fBitmap.isOpaque(); } - - /** Return the bitmap config of the device's pixels - */ - virtual SkBitmap::Config config() const SK_OVERRIDE { return fBitmap.config(); } - - /** - * DEPRECATED: This will be made protected once WebKit stops using it. - * Instead use Canvas' writePixels method. - * - * Similar to draw sprite, this method will copy the pixels in bitmap onto - * the device, with the top/left corner specified by (x, y). The pixel - * values in the device are completely replaced: there is no blending. - * - * Currently if bitmap is backed by a texture this is a no-op. This may be - * relaxed in the future. - * - * If the bitmap has config kARGB_8888_Config then the config8888 param - * will determines how the pixel valuess are intepreted. If the bitmap is - * not kARGB_8888_Config then this parameter is ignored. + * Construct a new device with the specified bitmap as its backend. It is + * valid for the bitmap to have no pixels associated with it. In that case, + * any drawing to this device will have no effect. */ - virtual void writePixels(const SkBitmap& bitmap, int x, int y, - SkCanvas::Config8888 config8888) SK_OVERRIDE; + SkBitmapDevice(const SkBitmap& bitmap, const SkSurfaceProps& surfaceProps); - /** - * Return the device's associated gpu render target, or NULL. - */ - virtual GrRenderTarget* accessRenderTarget() SK_OVERRIDE { return NULL; } + static SkBitmapDevice* Create(const SkImageInfo&, const SkSurfaceProps&); protected: - /** - * Device may filter the text flags for drawing text here. If it wants to - * make a change to the specified values, it should write them into the - * textflags parameter (output) and return true. If the paint is fine as - * is, then ignore the textflags parameter and return false. - * - * The baseclass SkDevice filters based on its depth and blitters. - */ - virtual bool filterTextFlags(const SkPaint& paint, TextFlags*) SK_OVERRIDE; - - /** Clears the entire device to the specified color (including alpha). - * Ignores the clip. - */ - virtual void clear(SkColor color) SK_OVERRIDE; + bool onShouldDisableLCD(const SkPaint&) const override; /** These are called inside the per-device-layer loop for each draw call. When these are called, we have already applied any saveLayer operations, and are handling any looping from the paint, and any effects from the DrawFilter. */ - virtual void drawPaint(const SkDraw&, const SkPaint& paint) SK_OVERRIDE; + void drawPaint(const SkDraw&, const SkPaint& paint) override; virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode, size_t count, - const SkPoint[], const SkPaint& paint) SK_OVERRIDE; + const SkPoint[], const SkPaint& paint) override; virtual void drawRect(const SkDraw&, const SkRect& r, - const SkPaint& paint) SK_OVERRIDE; + const SkPaint& paint) override; virtual void drawOval(const SkDraw&, const SkRect& oval, - const SkPaint& paint) SK_OVERRIDE; + const SkPaint& paint) override; virtual void drawRRect(const SkDraw&, const SkRRect& rr, - const SkPaint& paint) SK_OVERRIDE; + const SkPaint& paint) override; /** * If pathIsMutable, then the implementation is allowed to cast path to a @@ -150,46 +89,41 @@ class SK_API SkBitmapDevice : public SkBaseDevice { virtual void drawPath(const SkDraw&, const SkPath& path, const SkPaint& paint, const SkMatrix* prePathMatrix = NULL, - bool pathIsMutable = false) SK_OVERRIDE; + bool pathIsMutable = false) override; virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap, - const SkMatrix& matrix, const SkPaint& paint) SK_OVERRIDE; + const SkMatrix& matrix, const SkPaint& paint) override; virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap, - int x, int y, const SkPaint& paint) SK_OVERRIDE; + int x, int y, const SkPaint& paint) override; /** * The default impl. will create a bitmap-shader from the bitmap, * and call drawRect with it. */ - virtual void drawBitmapRect(const SkDraw&, const SkBitmap&, - const SkRect* srcOrNull, const SkRect& dst, - const SkPaint& paint, - SkCanvas::DrawBitmapRectFlags flags) SK_OVERRIDE; + void drawBitmapRect(const SkDraw&, const SkBitmap&, const SkRect*, const SkRect&, + const SkPaint&, SkCanvas::SrcRectConstraint) override; /** * Does not handle text decoration. * Decorations (underline and stike-thru) will be handled by SkCanvas. */ virtual void drawText(const SkDraw&, const void* text, size_t len, - SkScalar x, SkScalar y, const SkPaint& paint) SK_OVERRIDE; + SkScalar x, SkScalar y, const SkPaint& paint) override; virtual void drawPosText(const SkDraw&, const void* text, size_t len, - const SkScalar pos[], SkScalar constY, - int scalarsPerPos, const SkPaint& paint) SK_OVERRIDE; - virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len, - const SkPath& path, const SkMatrix* matrix, - const SkPaint& paint) SK_OVERRIDE; + const SkScalar pos[], int scalarsPerPos, + const SkPoint& offset, const SkPaint& paint) override; virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCount, const SkPoint verts[], const SkPoint texs[], - const SkColor colors[], SkXfermode* xmode, + const SkColor colors[], SkBlendMode, const uint16_t indices[], int indexCount, - const SkPaint& paint) SK_OVERRIDE; - /** The SkBaseDevice passed will be an SkBaseDevice which was returned by a call to - onCreateCompatibleDevice on this device with kSaveLayer_Usage. - */ - virtual void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y, - const SkPaint&) SK_OVERRIDE; + const SkPaint& paint) override; + virtual void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y, const SkPaint&) override; + + /////////////////////////////////////////////////////////////////////////// - // MM-2013-08-16: [[ RefactorGraphics ]] Expose drawDevMask. Used to render masks produced by platform specific text rendering procedures. - virtual void drawDevMask(const SkDraw&, const SkMask&, const SkPaint&); + void drawSpecial(const SkDraw&, SkSpecialImage*, int x, int y, const SkPaint&) override; + sk_sp makeSpecial(const SkBitmap&) override; + sk_sp makeSpecial(const SkImage*) override; + sk_sp snapSpecial() override; /////////////////////////////////////////////////////////////////////////// @@ -198,58 +132,23 @@ class SK_API SkBitmapDevice : public SkBaseDevice { altered. The config/width/height/rowbytes must remain unchanged. @return the device contents as a bitmap */ - virtual const SkBitmap& onAccessBitmap() SK_OVERRIDE; +#ifdef SK_SUPPORT_LEGACY_ACCESSBITMAP + const SkBitmap& onAccessBitmap() override; +#else + const SkBitmap& onAccessBitmap(); +#endif SkPixelRef* getPixelRef() const { return fBitmap.pixelRef(); } // just for subclasses, to assign a custom pixelref - SkPixelRef* setPixelRef(SkPixelRef* pr, size_t offset) { - fBitmap.setPixelRef(pr, offset); + SkPixelRef* setPixelRef(SkPixelRef* pr) { + fBitmap.setPixelRef(pr); return pr; } - /** - * Implements readPixels API. The caller will ensure that: - * 1. bitmap has pixel config kARGB_8888_Config. - * 2. bitmap has pixels. - * 3. The rectangle (x, y, x + bitmap->width(), y + bitmap->height()) is - * contained in the device bounds. - */ - virtual bool onReadPixels(const SkBitmap& bitmap, - int x, int y, - SkCanvas::Config8888 config8888) SK_OVERRIDE; - - /** Called when this device is installed into a Canvas. Balanced by a call - to unlockPixels() when the device is removed from a Canvas. - */ - virtual void lockPixels() SK_OVERRIDE; - virtual void unlockPixels() SK_OVERRIDE; - - /** - * Returns true if the device allows processing of this imagefilter. If - * false is returned, then the filter is ignored. This may happen for - * some subclasses that do not support pixel manipulations after drawing - * has occurred (e.g. printing). The default implementation returns true. - */ - virtual bool allowImageFilter(SkImageFilter*) SK_OVERRIDE; - - /** - * Override and return true for filters that the device can handle - * intrinsically. Doing so means that SkCanvas will pass-through this - * filter to drawSprite and drawDevice (and potentially filterImage). - * Returning false means the SkCanvas will have apply the filter itself, - * and just pass the resulting image to the device. - */ - virtual bool canHandleImageFilter(SkImageFilter*) SK_OVERRIDE; - - /** - * Related (but not required) to canHandleImageFilter, this method returns - * true if the device could apply the filter to the src bitmap and return - * the result (and updates offset as needed). - * If the device does not recognize or support this filter, - * it just returns false and leaves result and offset unchanged. - */ - virtual bool filterImage(SkImageFilter*, const SkBitmap&, const SkMatrix&, - SkBitmap* result, SkIPoint* offset) SK_OVERRIDE; + bool onReadPixels(const SkImageInfo&, void*, size_t, int x, int y) override; + bool onWritePixels(const SkImageInfo&, const void*, size_t, int, int) override; + bool onPeekPixels(SkPixmap*) override; + bool onAccessPixels(SkPixmap*) override; private: friend class SkCanvas; @@ -257,31 +156,24 @@ class SK_API SkBitmapDevice : public SkBaseDevice { friend class SkDraw; friend class SkDrawIter; friend class SkDeviceFilteredPaint; - friend class SkDeviceImageFilterProxy; friend class SkSurface_Raster; - void init(SkBitmap::Config config, int width, int height, bool isOpaque); - // used to change the backend's pixels (and possibly config/rowbytes) // but cannot change the width/height, so there should be no change to // any clip information. - virtual void replaceBitmapBackendForRasterSurface(const SkBitmap&) SK_OVERRIDE; + void replaceBitmapBackendForRasterSurface(const SkBitmap&) override; - /** - * Subclasses should override this to implement createCompatibleDevice. - */ - virtual SkBaseDevice* onCreateCompatibleDevice(SkBitmap::Config config, - int width, int height, - bool isOpaque, - Usage usage) SK_OVERRIDE; + SkBaseDevice* onCreateDevice(const CreateInfo&, const SkPaint*) override; - /** Causes any deferred drawing to the device to be completed. - */ - virtual void flush() SK_OVERRIDE {} + sk_sp makeSurface(const SkImageInfo&, const SkSurfaceProps&) override; + + SkImageFilterCache* getImageFilterCache() override; SkBitmap fBitmap; + void setNewSize(const SkISize&); // Used by SkCanvas for resetForNextPicture(). + typedef SkBaseDevice INHERITED; }; diff --git a/libskia/include/core/SkBlendMode.h b/libskia/include/core/SkBlendMode.h new file mode 100644 index 00000000..3f8f30c5 --- /dev/null +++ b/libskia/include/core/SkBlendMode.h @@ -0,0 +1,58 @@ +/* + * Copyright 2016 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkBlendMode_DEFINED +#define SkBlendMode_DEFINED + +#include "SkTypes.h" + +enum class SkBlendMode { + kClear, //!< [0, 0] + kSrc, //!< [Sa, Sc] + kDst, //!< [Da, Dc] + kSrcOver, //!< [Sa + Da * (1 - Sa), Sc + Dc * (1 - Sa)] + kDstOver, //!< [Da + Sa * (1 - Da), Dc + Sc * (1 - Da)] + kSrcIn, //!< [Sa * Da, Sc * Da] + kDstIn, //!< [Da * Sa, Dc * Sa] + kSrcOut, //!< [Sa * (1 - Da), Sc * (1 - Da)] + kDstOut, //!< [Da * (1 - Sa), Dc * (1 - Sa)] + kSrcATop, //!< [Da, Sc * Da + Dc * (1 - Sa)] + kDstATop, //!< [Sa, Dc * Sa + Sc * (1 - Da)] + kXor, //!< [Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + Dc * (1 - Sa)] + kPlus, //!< [Sa + Da, Sc + Dc] + kModulate, // multiplies all components (= alpha and color) + + // Following blend modes are defined in the CSS Compositing standard: + // https://dvcs.w3.org/hg/FXTF/rawfile/tip/compositing/index.html#blending + kScreen, + kLastCoeffMode = kScreen, + + kOverlay, + kDarken, + kLighten, + kColorDodge, + kColorBurn, + kHardLight, + kSoftLight, + kDifference, + kExclusion, + kMultiply, + kLastSeparableMode = kMultiply, + + kHue, + kSaturation, + kColor, + kLuminosity, + kLastMode = kLuminosity +}; + +/** + * Return the (c-string) name of the blendmode. + */ +SK_API const char* SkBlendMode_Name(SkBlendMode); + +#endif diff --git a/libskia/include/core/SkBlitRow.h b/libskia/include/core/SkBlitRow.h index 50113423..56121eba 100644 --- a/libskia/include/core/SkBlitRow.h +++ b/libskia/include/core/SkBlitRow.h @@ -26,17 +26,26 @@ class SkBlitRow { a corresponding scanline of 16bit colors (specific format based on the config passed to the Factory. - The x,y params are useful just for dithering + The x,y params provide the dithering phase for the start of the scanline @param alpha A global alpha to be applied to all of the src colors @param x The x coordinate of the beginning of the scanline @param y THe y coordinate of the scanline */ - typedef void (*Proc)(uint16_t* dst, - const SkPMColor* src, - int count, U8CPU alpha, int x, int y); + typedef void (*Proc16)(uint16_t dst[], const SkPMColor src[], int count, + U8CPU alpha, int x, int y); - static Proc Factory(unsigned flags, SkBitmap::Config); + static Proc16 Factory16(unsigned flags); + + /** + * Function pointer that blends a single src color onto a scaline of dst colors. + * + * The x,y params provide the dithering phase for the start of the scanline + */ + typedef void (*ColorProc16)(uint16_t dst[], SkPMColor src, int count, int x, int y); + + // Note : we ignore the kGlobalAlpha_Flag setting, but do respect kSrcPixelAlpha_Flag + static ColorProc16 ColorFactory16(unsigned flags); ///////////// D32 version @@ -51,38 +60,15 @@ class SkBlitRow { @param count number of colors to blend @param alpha global alpha to be applied to all src colors */ - typedef void (*Proc32)(uint32_t* dst, - const SkPMColor* src, - int count, U8CPU alpha); + typedef void (*Proc32)(uint32_t dst[], const SkPMColor src[], int count, U8CPU alpha); static Proc32 Factory32(unsigned flags32); - /** Function pointer that blends a single color with a row of 32-bit colors - onto a 32-bit destination - */ - typedef void (*ColorProc)(SkPMColor* dst, const SkPMColor* src, int count, - SkPMColor color); - /** Blend a single color onto a row of S32 pixels, writing the result into a row of D32 pixels. src and dst may be the same memory, but if they are not, they may not overlap. */ - static void Color32(SkPMColor dst[], const SkPMColor src[], - int count, SkPMColor color); - - //! Public entry-point to return a blit function ptr - static ColorProc ColorProcFactory(); - - /** Function pointer that blends a single color onto a 32-bit rectangle. */ - typedef void (*ColorRectProc)(SkPMColor* dst, int width, int height, - size_t rowBytes, SkPMColor color); - - /** Blend a single color into a rectangle of D32 pixels. */ - static void ColorRect32(SkPMColor* dst, int width, int height, - size_t rowBytes, SkPMColor color); - - //! Public entry-point to return a blit function ptr - static ColorRectProc ColorRectProcFactory(); + static void Color32(SkPMColor dst[], const SkPMColor src[], int count, SkPMColor color); /** These static functions are called by the Factory and Factory32 functions, and should return either NULL, or a @@ -91,8 +77,9 @@ class SkBlitRow { */ static Proc32 PlatformProcs32(unsigned flags); - static Proc PlatformProcs565(unsigned flags); - static ColorProc PlatformColorProc(); + + static Proc16 PlatformFactory565(unsigned flags); + static ColorProc16 PlatformColorFactory565(unsigned flags); private: enum { diff --git a/libskia/include/core/SkBlurTypes.h b/libskia/include/core/SkBlurTypes.h new file mode 100644 index 00000000..afbec19b --- /dev/null +++ b/libskia/include/core/SkBlurTypes.h @@ -0,0 +1,29 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkBlurTypes_DEFINED +#define SkBlurTypes_DEFINED + +#include "SkTypes.h" + +enum SkBlurStyle { + kNormal_SkBlurStyle, //!< fuzzy inside and outside + kSolid_SkBlurStyle, //!< solid inside, fuzzy outside + kOuter_SkBlurStyle, //!< nothing inside, fuzzy outside + kInner_SkBlurStyle, //!< fuzzy inside, nothing outside + + kLastEnum_SkBlurStyle = kInner_SkBlurStyle +}; + +enum SkBlurQuality { + kLow_SkBlurQuality, //!< e.g. box filter + kHigh_SkBlurQuality, //!< e.g. 3-pass similar to gaussian + + kLastEnum_SkBlurQuality +}; + +#endif diff --git a/libskia/include/core/SkBounder.h b/libskia/include/core/SkBounder.h deleted file mode 100644 index 7368d09a..00000000 --- a/libskia/include/core/SkBounder.h +++ /dev/null @@ -1,93 +0,0 @@ - -/* - * Copyright 2006 The Android Open Source Project - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - - -#ifndef SkBounder_DEFINED -#define SkBounder_DEFINED - -#include "SkTypes.h" -#include "SkRefCnt.h" -#include "SkPoint.h" - -struct SkGlyph; -struct SkIRect; -struct SkPoint; -struct SkRect; -class SkPaint; -class SkPath; -class SkRegion; - -/** \class SkBounder - - Base class for intercepting the device bounds of shapes before they are drawn. - Install a subclass of this in your canvas. -*/ -class SkBounder : public SkRefCnt { -public: - SK_DECLARE_INST_COUNT(SkBounder) - - SkBounder(); - - /* Call to perform a clip test before calling onIRect. - Returns the result from onIRect. - */ - bool doIRect(const SkIRect&); - bool doIRectGlyph(const SkIRect& , int x, int y, const SkGlyph&); - -protected: - /** Override in your subclass. This is called with the device bounds of an - object (text, geometry, image) just before it is drawn. If your method - returns false, the drawing for that shape is aborted. If your method - returns true, drawing continues. The bounds your method receives have already - been transformed in to device coordinates, and clipped to the current clip. - */ - virtual bool onIRect(const SkIRect&) { - return false; - } - - /** Passed to onIRectGlyph with the information about the current glyph. - LSB and RSB are fixed-point (16.16) coordinates of the start and end - of the glyph's advance - */ - struct GlyphRec { - SkIPoint fLSB; //!< fixed-point left-side-bearing of the glyph - SkIPoint fRSB; //!< fixed-point right-side-bearing of the glyph - uint16_t fGlyphID; - uint16_t fFlags; //!< currently set to 0 - }; - - /** Optionally, override in your subclass to receive the glyph ID when - text drawing supplies the device bounds of the object. - */ - virtual bool onIRectGlyph(const SkIRect& r, const GlyphRec&) { - return onIRect(r); - } - - /** Called after each shape has been drawn. The default implementation does - nothing, but your override could use this notification to signal itself - that the offscreen being rendered into needs to be updated to the screen. - */ - virtual void commit(); - -private: - bool doHairline(const SkPoint&, const SkPoint&, const SkPaint&); - bool doRect(const SkRect&, const SkPaint&); - bool doPath(const SkPath&, const SkPaint&, bool doFill); - void setClip(const SkRegion* clip) { fClip = clip; } - - const SkRegion* fClip; - friend class SkAutoBounderCommit; - friend class SkDraw; - friend class SkDrawIter; - friend struct Draw1Glyph; - friend class SkMaskFilter; - - typedef SkRefCnt INHERITED; -}; - -#endif diff --git a/libskia/include/core/SkCanvas.h b/libskia/include/core/SkCanvas.h index 53882829..98872110 100644 --- a/libskia/include/core/SkCanvas.h +++ b/libskia/include/core/SkCanvas.h @@ -1,4 +1,3 @@ - /* * Copyright 2006 The Android Open Source Project * @@ -6,32 +5,44 @@ * found in the LICENSE file. */ - #ifndef SkCanvas_DEFINED #define SkCanvas_DEFINED #include "SkTypes.h" +#include "SkBlendMode.h" #include "SkBitmap.h" +#include "SkClipOp.h" #include "SkDeque.h" -#include "SkClipStack.h" +#include "SkImage.h" #include "SkPaint.h" #include "SkRefCnt.h" -#include "SkPath.h" #include "SkRegion.h" -#include "SkXfermode.h" - -// MM-2013-08-16: [[ RefactorGraphics ]] Expose drawDevMask. -#include "SkMask.h" +#include "SkSurfaceProps.h" +#include "SkLights.h" +#include "../private/SkShadowParams.h" -class SkBounder; +class GrContext; +class GrRenderTargetContext; class SkBaseDevice; +class SkCanvasClipVisitor; +class SkClipStack; +class SkData; class SkDraw; +class SkDrawable; class SkDrawFilter; +class SkImageFilter; class SkMetaData; +class SkPath; class SkPicture; +class SkPixmap; +class SkRasterClip; class SkRRect; +struct SkRSXform; +class SkSurface; class SkSurface_Base; -class GrContext; +class SkTextBlob; + +//#define SK_SUPPORT_LEGACY_CLIP_REGIONOPS /** \class SkCanvas @@ -48,12 +59,82 @@ class GrContext; color, typeface, textSize, strokeWidth, shader (e.g. gradients, patterns), etc. */ -class SK_API SkCanvas : public SkRefCnt { +class SK_API SkCanvas +#ifdef SK_SUPPORT_LEGACY_CANVAS_IS_REFCNT +: public SkRefCnt +#else +: SkNoncopyable +#endif +{ + enum PrivateSaveLayerFlags { + kDontClipToLayer_PrivateSaveLayerFlag = 1U << 31, + }; + public: - SK_DECLARE_INST_COUNT(SkCanvas) +#ifdef SK_SUPPORT_LEGACY_CLIP_REGIONOPS + typedef SkRegion::Op ClipOp; + + static const ClipOp kDifference_Op = SkRegion::kDifference_Op; + static const ClipOp kIntersect_Op = SkRegion::kIntersect_Op; + static const ClipOp kUnion_Op = SkRegion::kUnion_Op; + static const ClipOp kXOR_Op = SkRegion::kXOR_Op; + static const ClipOp kReverseDifference_Op = SkRegion::kReverseDifference_Op; + static const ClipOp kReplace_Op = SkRegion::kReplace_Op; +#else + typedef SkClipOp ClipOp; + + static const ClipOp kDifference_Op = kDifference_SkClipOp; + static const ClipOp kIntersect_Op = kIntersect_SkClipOp; + static const ClipOp kUnion_Op = kUnion_SkClipOp; + static const ClipOp kXOR_Op = kXOR_SkClipOp; + static const ClipOp kReverseDifference_Op = kReverseDifference_SkClipOp; + static const ClipOp kReplace_Op = kReplace_SkClipOp; +#endif + /** + * Attempt to allocate raster canvas, matching the ImageInfo, that will draw directly into the + * specified pixels. To access the pixels after drawing to them, the caller should call + * flush() or call peekPixels(...). + * + * On failure, return NULL. This can fail for several reasons: + * 1. invalid ImageInfo (e.g. negative dimensions) + * 2. unsupported ImageInfo for a canvas + * - kUnknown_SkColorType, kIndex_8_SkColorType + * - kUnknown_SkAlphaType + * - this list is not complete, so others may also be unsupported + * + * Note: it is valid to request a supported ImageInfo, but with zero + * dimensions. + */ + static std::unique_ptr MakeRasterDirect(const SkImageInfo&, void*, size_t); + static std::unique_ptr MakeRasterDirectN32(int width, int height, SkPMColor* pixels, + size_t rowBytes) { + return MakeRasterDirect(SkImageInfo::MakeN32Premul(width, height), pixels, rowBytes); + } + +#ifdef SK_SUPPORT_LEGACY_CANVAS_IS_REFCNT + static SkCanvas* NewRasterDirect(const SkImageInfo& info, void* pixels, size_t rowBytes) { + return MakeRasterDirect(info, pixels, rowBytes).release(); + } + + static SkCanvas* NewRasterDirectN32(int width, int height, SkPMColor* pixels, size_t rowBytes) { + return MakeRasterDirectN32(width, height, pixels, rowBytes).release(); + } +#endif + + /** + * Creates an empty canvas with no backing device/pixels, and zero + * dimensions. + */ SkCanvas(); + /** + * Creates a canvas of the specified dimensions, but explicitly not backed + * by any device/pixels. Typically this use used by subclasses who handle + * the draw calls in some other way. + */ + SkCanvas(int width, int height, const SkSurfaceProps* = NULL); + /** Construct a canvas with the specified device to draw into. @param device Specifies a device for the canvas to draw into. @@ -65,29 +146,66 @@ class SK_API SkCanvas : public SkRefCnt { structure are copied to the canvas. */ explicit SkCanvas(const SkBitmap& bitmap); + + /** Construct a canvas with the specified bitmap to draw into. + @param bitmap Specifies a bitmap for the canvas to draw into. Its + structure are copied to the canvas. + @param props New canvas surface properties. + */ + SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props); + virtual ~SkCanvas(); SkMetaData& getMetaData(); + /** + * Return ImageInfo for this canvas. If the canvas is not backed by pixels + * (cpu or gpu), then the info's ColorType will be kUnknown_SkColorType. + */ + SkImageInfo imageInfo() const; + + /** + * If the canvas is backed by pixels (cpu or gpu), this writes a copy of the SurfaceProps + * for the canvas to the location supplied by the caller, and returns true. Otherwise, + * return false and leave the supplied props unchanged. + */ + bool getProps(SkSurfaceProps*) const; + /////////////////////////////////////////////////////////////////////////// /** - * Trigger the immediate execution of all pending draw operations. + * Trigger the immediate execution of all pending draw operations. For the GPU + * backend this will resolve all rendering to the GPU surface backing the + * SkSurface that owns this canvas. */ void flush(); /** - * Return the width/height of the underlying device. The current drawable - * area may be small (due to clipping or saveLayer). For a canvas with - * no device, 0,0 will be returned. + * Gets the size of the base or root layer in global canvas coordinates. The + * origin of the base layer is always (0,0). The current drawable area may be + * smaller (due to clipping or saveLayer). */ - SkISize getDeviceSize() const; + virtual SkISize getBaseLayerSize() const; - /** Return the canvas' device object, which may be null. The device holds - the bitmap of the pixels that the canvas draws into. The reference count - of the returned device is not changed by this call. - */ + /** + * DEPRECATED: call getBaseLayerSize + */ + SkISize getDeviceSize() const { return this->getBaseLayerSize(); } + + /** + * DEPRECATED. + * Return the canvas' device object, which may be null. The device holds + * the bitmap of the pixels that the canvas draws into. The reference count + * of the returned device is not changed by this call. + */ +#ifndef SK_SUPPORT_LEGACY_GETDEVICE +protected: // Can we make this private? +#endif SkBaseDevice* getDevice() const; +public: + SkBaseDevice* getDevice_just_for_deprecated_compatibility_testing() const { + return this->getDevice(); + } /** * saveLayer() can create another device (which is later drawn onto @@ -102,15 +220,22 @@ class SK_API SkCanvas : public SkRefCnt { * is drawn to, but is optional here, as there is a small perf hit * sometimes. */ +#ifndef SK_SUPPORT_LEGACY_GETTOPDEVICE +private: +#endif SkBaseDevice* getTopDevice(bool updateMatrixClip = false) const; +public: /** - * Shortcut for getDevice()->createCompatibleDevice(...). - * If getDevice() == NULL, this method does nothing, and returns NULL. + * Create a new surface matching the specified info, one that attempts to + * be maximally compatible when used with this canvas. If there is no matching Surface type, + * NULL is returned. + * + * If surfaceprops is specified, those are passed to the new surface, otherwise the new surface + * inherits the properties of the surface that owns this canvas. If this canvas has no parent + * surface, then the new surface is created with default properties. */ - SkBaseDevice* createCompatibleDevice(SkBitmap::Config config, - int width, int height, - bool isOpaque); + sk_sp makeSurface(const SkImageInfo&, const SkSurfaceProps* = nullptr); /** * Return the GPU context of the device that is associated with the canvas. @@ -121,126 +246,95 @@ class SK_API SkCanvas : public SkRefCnt { /////////////////////////////////////////////////////////////////////////// /** - * This enum can be used with read/writePixels to perform a pixel ops to or - * from an 8888 config other than Skia's native config (SkPMColor). There - * are three byte orders supported: native, BGRA, and RGBA. Each has a - * premultiplied and unpremultiplied variant. + * If the canvas has writable pixels in its top layer (and is not recording to a picture + * or other non-raster target) and has direct access to its pixels (i.e. they are in + * local RAM) return the address of those pixels, and if not null, + * return the ImageInfo, rowBytes and origin. The returned address is only valid + * while the canvas object is in scope and unchanged. Any API calls made on + * canvas (or its parent surface if any) will invalidate the + * returned address (and associated information). * - * Components of a 8888 pixel can be packed/unpacked from a 32bit word using - * either byte offsets or shift values. Byte offsets are endian-invariant - * while shifts are not. BGRA and RGBA configs are defined by byte - * orderings. The native config is defined by shift values (SK_A32_SHIFT, - * ..., SK_B32_SHIFT). + * On failure, returns NULL and the info, rowBytes, and origin parameters are ignored. */ - enum Config8888 { - /** - * Skia's native order specified by: - * SK_A32_SHIFT, SK_R32_SHIFT, SK_G32_SHIFT, and SK_B32_SHIFT - * - * kNative_Premul_Config8888 is equivalent to SkPMColor - * kNative_Unpremul_Config8888 has the same component order as SkPMColor - * but is not premultiplied. - */ - kNative_Premul_Config8888, - kNative_Unpremul_Config8888, - /** - * low byte to high byte: B, G, R, A. - */ - kBGRA_Premul_Config8888, - kBGRA_Unpremul_Config8888, - /** - * low byte to high byte: R, G, B, A. - */ - kRGBA_Premul_Config8888, - kRGBA_Unpremul_Config8888 - }; + void* accessTopLayerPixels(SkImageInfo* info, size_t* rowBytes, SkIPoint* origin = NULL); /** - * On success (returns true), copy the canvas pixels into the bitmap. - * On failure, the bitmap parameter is left unchanged and false is - * returned. + * If the canvas has readable pixels in its base layer (and is not recording to a picture + * or other non-raster target) and has direct access to its pixels (i.e. they are in + * local RAM) return true, and if not null, return in the pixmap parameter information about + * the pixels. The pixmap's pixel address is only valid + * while the canvas object is in scope and unchanged. Any API calls made on + * canvas (or its parent surface if any) will invalidate the pixel address + * (and associated information). * - * The canvas' pixels are converted to the bitmap's config. The only - * supported config is kARGB_8888_Config, though this is likely to be - * relaxed in the future. The meaning of config kARGB_8888_Config is - * modified by the enum param config8888. The default value interprets - * kARGB_8888_Config as SkPMColor + * On failure, returns false and the pixmap parameter will be ignored. + */ + bool peekPixels(SkPixmap*); + + /** + * Copy the pixels from the base-layer into the specified buffer (pixels + rowBytes), + * converting them into the requested format (SkImageInfo). The base-layer pixels are read + * starting at the specified (srcX,srcY) location in the coordinate system of the base-layer. * - * If the bitmap has pixels already allocated, the canvas pixels will be - * written there. If not, bitmap->allocPixels() will be called - * automatically. If the bitmap is backed by a texture readPixels will - * fail. + * The specified ImageInfo and (srcX,srcY) offset specifies a source rectangle * - * The actual pixels written is the intersection of the canvas' bounds, and - * the rectangle formed by the bitmap's width,height and the specified x,y. - * If bitmap pixels extend outside of that intersection, they will not be - * modified. + * srcR.setXYWH(srcX, srcY, dstInfo.width(), dstInfo.height()); * - * Other failure conditions: - * * If the canvas is backed by a non-raster device (e.g. PDF) then - * readPixels will fail. - * * If bitmap is texture-backed then readPixels will fail. (This may be - * relaxed in the future.) + * srcR is intersected with the bounds of the base-layer. If this intersection is not empty, + * then we have two sets of pixels (of equal size). Replace the dst pixels with the + * corresponding src pixels, performing any colortype/alphatype transformations needed + * (in the case where the src and dst have different colortypes or alphatypes). * - * Example that reads the entire canvas into a bitmap using the native - * SkPMColor: - * SkISize size = canvas->getDeviceSize(); - * bitmap->setConfig(SkBitmap::kARGB_8888_Config, size.fWidth, - * size.fHeight); - * if (canvas->readPixels(bitmap, 0, 0)) { - * // use the pixels - * } + * This call can fail, returning false, for several reasons: + * - If srcR does not intersect the base-layer bounds. + * - If the requested colortype/alphatype cannot be converted from the base-layer's types. + * - If this canvas is not backed by pixels (e.g. picture or PDF) */ - bool readPixels(SkBitmap* bitmap, - int x, int y, - Config8888 config8888 = kNative_Premul_Config8888); + bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes, + int srcX, int srcY); /** - * DEPRECATED: This will be removed as soon as webkit is no longer relying - * on it. The bitmap is resized to the intersection of srcRect and the - * canvas bounds. New pixels are always allocated on success. Bitmap is - * unmodified on failure. + * Helper for calling readPixels(info, ...). This call will check if bitmap has been allocated. + * If not, it will attempt to call allocPixels(). If this fails, it will return false. If not, + * it calls through to readPixels(info, ...) and returns its result. + */ + bool readPixels(SkBitmap* bitmap, int srcX, int srcY); + + /** + * Helper for allocating pixels and then calling readPixels(info, ...). The bitmap is resized + * to the intersection of srcRect and the base-layer bounds. On success, pixels will be + * allocated in bitmap and true returned. On failure, false is returned and bitmap will be + * set to empty. */ bool readPixels(const SkIRect& srcRect, SkBitmap* bitmap); /** - * Similar to draw sprite, this method will copy the pixels in bitmap onto - * the canvas, with the top/left corner specified by (x, y). The canvas' - * pixel values are completely replaced: there is no blending. + * This method affects the pixels in the base-layer, and operates in pixel coordinates, + * ignoring the matrix and clip. + * + * The specified ImageInfo and (x,y) offset specifies a rectangle: target. * - * Currently if bitmap is backed by a texture this is a no-op. This may be - * relaxed in the future. + * target.setXYWH(x, y, info.width(), info.height()); * - * If the bitmap has config kARGB_8888_Config then the config8888 param - * will determines how the pixel valuess are intepreted. If the bitmap is - * not kARGB_8888_Config then this parameter is ignored. + * Target is intersected with the bounds of the base-layer. If this intersection is not empty, + * then we have two sets of pixels (of equal size), the "src" specified by info+pixels+rowBytes + * and the "dst" by the canvas' backend. Replace the dst pixels with the corresponding src + * pixels, performing any colortype/alphatype transformations needed (in the case where the + * src and dst have different colortypes or alphatypes). * - * Note: If you are recording drawing commands on this canvas to - * SkPicture, writePixels() is ignored! + * This call can fail, returning false, for several reasons: + * - If the src colortype/alphatype cannot be converted to the canvas' types + * - If this canvas is not backed by pixels (e.g. picture or PDF) */ - void writePixels(const SkBitmap& bitmap, - int x, int y, - Config8888 config8888 = kNative_Premul_Config8888); + bool writePixels(const SkImageInfo&, const void* pixels, size_t rowBytes, int x, int y); - /////////////////////////////////////////////////////////////////////////// + /** + * Helper for calling writePixels(info, ...) by passing its pixels and rowbytes. If the bitmap + * is just wrapping a texture, returns false and does nothing. + */ + bool writePixels(const SkBitmap& bitmap, int x, int y); - enum SaveFlags { - /** save the matrix state, restoring it on restore() */ - kMatrix_SaveFlag = 0x01, - /** save the clip state, restoring it on restore() */ - kClip_SaveFlag = 0x02, - /** the layer needs to support per-pixel alpha */ - kHasAlphaLayer_SaveFlag = 0x04, - /** the layer needs to support 8-bits per color component */ - kFullColorLayer_SaveFlag = 0x08, - /** the layer should clip against the bounds argument */ - kClipToLayer_SaveFlag = 0x10, - - // helper masks for common choices - kMatrixClip_SaveFlag = 0x03, - kARGB_NoClipLayer_SaveFlag = 0x0F, - kARGB_ClipLayer_SaveFlag = 0x1F - }; + /////////////////////////////////////////////////////////////////////////// /** This call saves the current matrix, clip, and drawFilter, and pushes a copy onto a private stack. Subsequent calls to translate, scale, @@ -248,15 +342,10 @@ class SK_API SkCanvas : public SkRefCnt { operate on this copy. When the balancing call to restore() is made, the previous matrix, clip, and drawFilter are restored. - @param flags The flags govern what portion of the Matrix/Clip/drawFilter - state the save (and matching restore) effect. For example, - if only kMatrix is specified, then only the matrix state - will be pushed and popped. Likewise for the clip if kClip - is specified. However, the drawFilter is always affected - by calls to save/restore. + @return The value to pass to restoreToCount() to balance this save() */ - virtual int save(SaveFlags flags = kMatrixClip_SaveFlag); + int save(); /** This behaves the same as save(), but in addition it allocates an offscreen bitmap. All drawing calls are directed there, and only when @@ -268,11 +357,19 @@ class SK_API SkCanvas : public SkRefCnt { happen. If exact clipping is desired, use clipRect(). @param paint (may be null) This is copied, and is applied to the offscreen when restore() is called - @param flags LayerFlags @return The value to pass to restoreToCount() to balance this save() */ - virtual int saveLayer(const SkRect* bounds, const SkPaint* paint, - SaveFlags flags = kARGB_ClipLayer_SaveFlag); + int saveLayer(const SkRect* bounds, const SkPaint* paint); + int saveLayer(const SkRect& bounds, const SkPaint* paint) { + return this->saveLayer(&bounds, paint); + } + + /** + * Temporary name. + * Will allow any requests for LCD text to be respected, so the caller must be careful to + * only draw on top of opaque sections of the layer to get good results. + */ + int saveLayerPreserveLCDTextRequests(const SkRect* bounds, const SkPaint* paint); /** This behaves the same as save(), but in addition it allocates an offscreen bitmap. All drawing calls are directed there, and only when @@ -283,117 +380,169 @@ class SK_API SkCanvas : public SkRefCnt { clipped to it, though that clipping is not guaranteed to happen. If exact clipping is desired, use clipRect(). @param alpha This is applied to the offscreen when restore() is called. - @param flags LayerFlags @return The value to pass to restoreToCount() to balance this save() */ - int saveLayerAlpha(const SkRect* bounds, U8CPU alpha, - SaveFlags flags = kARGB_ClipLayer_SaveFlag); + int saveLayerAlpha(const SkRect* bounds, U8CPU alpha); + + enum { + kIsOpaque_SaveLayerFlag = 1 << 0, + kPreserveLCDText_SaveLayerFlag = 1 << 1, + +#ifdef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG + kDontClipToLayer_Legacy_SaveLayerFlag = kDontClipToLayer_PrivateSaveLayerFlag, +#endif + }; + typedef uint32_t SaveLayerFlags; + + struct SaveLayerRec { + SaveLayerRec() + : fBounds(nullptr), fPaint(nullptr), fBackdrop(nullptr), fSaveLayerFlags(0) + {} + SaveLayerRec(const SkRect* bounds, const SkPaint* paint, SaveLayerFlags saveLayerFlags = 0) + : fBounds(bounds) + , fPaint(paint) + , fBackdrop(nullptr) + , fSaveLayerFlags(saveLayerFlags) + {} + SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop, + SaveLayerFlags saveLayerFlags) + : fBounds(bounds) + , fPaint(paint) + , fBackdrop(backdrop) + , fSaveLayerFlags(saveLayerFlags) + {} + + const SkRect* fBounds; // optional + const SkPaint* fPaint; // optional + const SkImageFilter* fBackdrop; // optional + SaveLayerFlags fSaveLayerFlags; + }; + + int saveLayer(const SaveLayerRec&); /** This call balances a previous call to save(), and is used to remove all modifications to the matrix/clip/drawFilter state since the last save call. It is an error to call restore() more times than save() was called. */ - virtual void restore(); + void restore(); /** Returns the number of matrix/clip states on the SkCanvas' private stack. - This will equal # save() calls - # restore() calls. + This will equal # save() calls - # restore() calls + 1. The save count on + a new canvas is 1. */ int getSaveCount() const; /** Efficient way to pop any calls to save() that happened after the save - count reached saveCount. It is an error for saveCount to be less than - getSaveCount() + count reached saveCount. It is an error for saveCount to be greater than + getSaveCount(). To pop all the way back to the initial matrix/clip context + pass saveCount == 1. @param saveCount The number of save() levels to restore from */ void restoreToCount(int saveCount); - /** Returns true if drawing is currently going to a layer (from saveLayer) - * rather than to the root device. - */ - virtual bool isDrawingToLayer() const; - /** Preconcat the current matrix with the specified translation @param dx The distance to translate in X @param dy The distance to translate in Y - returns true if the operation succeeded (e.g. did not overflow) */ - virtual bool translate(SkScalar dx, SkScalar dy); + void translate(SkScalar dx, SkScalar dy); /** Preconcat the current matrix with the specified scale. @param sx The amount to scale in X @param sy The amount to scale in Y - returns true if the operation succeeded (e.g. did not overflow) */ - virtual bool scale(SkScalar sx, SkScalar sy); + void scale(SkScalar sx, SkScalar sy); + + /** Preconcat the current matrix with the specified rotation about the origin. + @param degrees The amount to rotate, in degrees + */ + void rotate(SkScalar degrees); - /** Preconcat the current matrix with the specified rotation. + /** Preconcat the current matrix with the specified rotation about a given point. @param degrees The amount to rotate, in degrees - returns true if the operation succeeded (e.g. did not overflow) + @param px The x coordinate of the point to rotate about. + @param py The y coordinate of the point to rotate about. */ - virtual bool rotate(SkScalar degrees); + void rotate(SkScalar degrees, SkScalar px, SkScalar py); /** Preconcat the current matrix with the specified skew. @param sx The amount to skew in X @param sy The amount to skew in Y - returns true if the operation succeeded (e.g. did not overflow) */ - virtual bool skew(SkScalar sx, SkScalar sy); + void skew(SkScalar sx, SkScalar sy); /** Preconcat the current matrix with the specified matrix. @param matrix The matrix to preconcatenate with the current matrix - @return true if the operation succeeded (e.g. did not overflow) */ - virtual bool concat(const SkMatrix& matrix); + void concat(const SkMatrix& matrix); /** Replace the current matrix with a copy of the specified matrix. @param matrix The matrix that will be copied into the current matrix. */ - virtual void setMatrix(const SkMatrix& matrix); + void setMatrix(const SkMatrix& matrix); /** Helper for setMatrix(identity). Sets the current matrix to identity. */ void resetMatrix(); +#ifdef SK_EXPERIMENTAL_SHADOWING + /** Add the specified translation to the current draw depth of the canvas. + @param z The distance to translate in Z. + Negative into screen, positive out of screen. + Without translation, the draw depth defaults to 0. + */ + void translateZ(SkScalar z); + + /** Set the current set of lights in the canvas. + @param lights The lights that we want the canvas to have. + */ + void setLights(sk_sp lights); + + /** Returns the current set of lights the canvas uses + */ + sk_sp getLights() const; +#endif + /** * Modify the current clip with the specified rectangle. * @param rect The rect to combine with the current clip * @param op The region op to apply to the current clip * @param doAntiAlias true if the clip should be antialiased - * @return true if the canvas' clip is non-empty */ - virtual bool clipRect(const SkRect& rect, - SkRegion::Op op = SkRegion::kIntersect_Op, - bool doAntiAlias = false); + void clipRect(const SkRect& rect, ClipOp, bool doAntiAlias); + void clipRect(const SkRect& rect, ClipOp op) { + this->clipRect(rect, op, false); + } + void clipRect(const SkRect& rect, bool doAntiAlias = false) { + this->clipRect(rect, kIntersect_Op, doAntiAlias); + } /** * Modify the current clip with the specified SkRRect. * @param rrect The rrect to combine with the current clip * @param op The region op to apply to the current clip * @param doAntiAlias true if the clip should be antialiased - * @return true if the canvas' clip is non-empty */ - virtual bool clipRRect(const SkRRect& rrect, - SkRegion::Op op = SkRegion::kIntersect_Op, - bool doAntiAlias = false); + void clipRRect(const SkRRect& rrect, ClipOp op, bool doAntiAlias); + void clipRRect(const SkRRect& rrect, ClipOp op) { + this->clipRRect(rrect, op, false); + } + void clipRRect(const SkRRect& rrect, bool doAntiAlias = false) { + this->clipRRect(rrect, kIntersect_Op, doAntiAlias); + } /** * Modify the current clip with the specified path. * @param path The path to combine with the current clip * @param op The region op to apply to the current clip * @param doAntiAlias true if the clip should be antialiased - * @return true if the canvas' new clip is non-empty */ - virtual bool clipPath(const SkPath& path, - SkRegion::Op op = SkRegion::kIntersect_Op, - bool doAntiAlias = false); - - /** EXPERIMENTAL -- only used for testing - Set to false to force clips to be hard, even if doAntiAlias=true is - passed to clipRect or clipPath. - */ - void setAllowSoftClip(bool allow) { - fAllowSoftClip = allow; + void clipPath(const SkPath& path, ClipOp op, bool doAntiAlias); + void clipPath(const SkPath& path, ClipOp op) { + this->clipPath(path, op, false); + } + void clipPath(const SkPath& path, bool doAntiAlias = false) { + this->clipPath(path, kIntersect_Op, doAntiAlias); } /** EXPERIMENTAL -- only used for testing @@ -409,20 +558,8 @@ class SK_API SkCanvas : public SkRefCnt { coordinates, and so no transformation is performed. @param deviceRgn The region to apply to the current clip @param op The region op to apply to the current clip - @return true if the canvas' new clip is non-empty - */ - virtual bool clipRegion(const SkRegion& deviceRgn, - SkRegion::Op op = SkRegion::kIntersect_Op); - - /** Helper for clipRegion(rgn, kReplace_Op). Sets the current clip to the - specified region. This does not intersect or in any other way account - for the existing clip region. - @param deviceRgn The region to copy into the current clip. - @return true if the new clip region is non-empty */ - bool setClipRegion(const SkRegion& deviceRgn) { - return this->clipRegion(deviceRgn, SkRegion::kReplace_Op); - } + void clipRegion(const SkRegion& deviceRgn, ClipOp op = kIntersect_Op); /** Return true if the specified rectangle, after being transformed by the current matrix, would lie completely outside of the current clip. Call @@ -446,38 +583,18 @@ class SK_API SkCanvas : public SkRefCnt { */ bool quickReject(const SkPath& path) const; - /** Return true if the horizontal band specified by top and bottom is - completely clipped out. This is a conservative calculation, meaning - that it is possible that if the method returns false, the band may still - in fact be clipped out, but the converse is not true. If this method - returns true, then the band is guaranteed to be clipped out. - @param top The top of the horizontal band to compare with the clip - @param bottom The bottom of the horizontal and to compare with the clip - @return true if the horizontal band is completely clipped out (i.e. does - not intersect the current clip) - */ - bool quickRejectY(SkScalar top, SkScalar bottom) const { - SkASSERT(top <= bottom); - const SkRect& clipR = this->getLocalClipBounds(); - // In the case where the clip is empty and we are provided with a - // negative top and positive bottom parameter then this test will return - // false even though it will be clipped. We have chosen to exclude that - // check as it is rare and would result double the comparisons. - return top >= clipR.fBottom || bottom <= clipR.fTop; - } - /** Return the bounds of the current clip (in local coordinates) in the bounds parameter, and return true if it is non-empty. This can be useful in a way similar to quickReject, in that it tells you that drawing outside of these bounds will be clipped out. */ - bool getClipBounds(SkRect* bounds) const; + virtual bool getClipBounds(SkRect* bounds) const; /** Return the bounds of the current clip, in device coordinates; returns true if non-empty. Maybe faster than getting the clip explicitly and then taking its bounds. */ - bool getClipDeviceBounds(SkIRect* bounds) const; + virtual bool getClipDeviceBounds(SkIRect* bounds) const; /** Fill the entire canvas' bitmap (restricted to the current clip) with the @@ -488,39 +605,43 @@ class SK_API SkCanvas : public SkRefCnt { @param b the blue component (0..255) of the color to fill the canvas @param mode the mode to apply the color in (defaults to SrcOver) */ - void drawARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b, - SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode); + void drawARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b, SkBlendMode mode = SkBlendMode::kSrcOver); /** Fill the entire canvas' bitmap (restricted to the current clip) with the specified color and mode. @param color the color to draw with @param mode the mode to apply the color in (defaults to SrcOver) */ - void drawColor(SkColor color, - SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode); + void drawColor(SkColor color, SkBlendMode mode = SkBlendMode::kSrcOver); + + /** + * Helper method for drawing a color in SRC mode, completely replacing all the pixels + * in the current clip with this color. + */ + void clear(SkColor color) { + this->drawColor(color, SkBlendMode::kSrc); + } /** - * This erases the entire drawing surface to the specified color, - * irrespective of the clip. It does not blend with the previous pixels, - * but always overwrites them. + * This makes the contents of the canvas undefined. Subsequent calls that + * require reading the canvas contents will produce undefined results. Examples + * include blending and readPixels. The actual implementation is backend- + * dependent and one legal implementation is to do nothing. This method + * ignores the current clip. * - * It is roughly equivalent to the following: - * canvas.save(); - * canvas.clipRect(hugeRect, kReplace_Op); - * paint.setColor(color); - * paint.setXfermodeMode(kSrc_Mode); - * canvas.drawPaint(paint); - * canvas.restore(); - * though it is almost always much more efficient. + * This function should only be called if the caller intends to subsequently + * draw to the canvas. The canvas may do real work at discard() time in order + * to optimize performance on subsequent draws. Thus, if you call this and then + * never draw to the canvas subsequently you may pay a perfomance penalty. */ - virtual void clear(SkColor); + void discard() { this->onDiscard(); } /** - * Fill the entire canvas' bitmap (restricted to the current clip) with the + * Fill the entire canvas (restricted to the current clip) with the * specified paint. * @param paint The paint used to fill the canvas */ - virtual void drawPaint(const SkPaint& paint); + void drawPaint(const SkPaint& paint); enum PointMode { /** drawPoints draws each point separately */ @@ -552,8 +673,7 @@ class SK_API SkCanvas : public SkRefCnt { @param pts Array of points to draw @param paint The paint used to draw the points */ - virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[], - const SkPaint& paint); + void drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint); /** Helper method for drawing a single point. See drawPoints() for a more details. @@ -584,15 +704,14 @@ class SK_API SkCanvas : public SkRefCnt { @param rect The rect to be drawn @param paint The paint used to draw the rect */ - virtual void drawRect(const SkRect& rect, const SkPaint& paint); + void drawRect(const SkRect& rect, const SkPaint& paint); /** Draw the specified rectangle using the specified paint. The rectangle will be filled or framed based on the Style in the paint. @param rect The rect to be drawn @param paint The paint used to draw the rect */ - void drawIRect(const SkIRect& rect, const SkPaint& paint) - { + void drawIRect(const SkIRect& rect, const SkPaint& paint) { SkRect r; r.set(rect); // promotes the ints to scalars this->drawRect(r, paint); @@ -609,12 +728,18 @@ class SK_API SkCanvas : public SkRefCnt { void drawRectCoords(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom, const SkPaint& paint); + /** Draw the outline of the specified region using the specified paint. + @param region The region to be drawn + @param paint The paint used to draw the region + */ + void drawRegion(const SkRegion& region, const SkPaint& paint); + /** Draw the specified oval using the specified paint. The oval will be filled or framed based on the Style in the paint. @param oval The rectangle bounds of the oval to be drawn @param paint The paint used to draw the oval */ - virtual void drawOval(const SkRect& oval, const SkPaint&); + void drawOval(const SkRect& oval, const SkPaint&); /** * Draw the specified RRect using the specified paint The rrect will be filled or stroked @@ -623,7 +748,13 @@ class SK_API SkCanvas : public SkRefCnt { * @param rrect The round-rect to draw * @param paint The paint used to draw the round-rect */ - virtual void drawRRect(const SkRRect& rrect, const SkPaint& paint); + void drawRRect(const SkRRect& rrect, const SkPaint& paint); + + /** + * Draw the annulus formed by the outer and inner rrects. The results + * are undefined if the outer does not contain the inner. + */ + void drawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint&); /** Draw the specified circle using the specified paint. If radius is <= 0, then nothing will be drawn. The circle will be filled @@ -637,14 +768,17 @@ class SK_API SkCanvas : public SkRefCnt { const SkPaint& paint); /** Draw the specified arc, which will be scaled to fit inside the - specified oval. If the sweep angle is >= 360, then the oval is drawn - completely. Note that this differs slightly from SkPath::arcTo, which - treats the sweep angle mod 360. - @param oval The bounds of oval used to define the shape of the arc + specified oval. Sweep angles are not treated as modulo 360 and thus can + exceed a full sweep of the oval. Note that this differs slightly from + SkPath::arcTo, which treats the sweep angle mod 360. If the oval is empty + or the sweep angle is zero nothing is drawn. If useCenter is true the oval + center is inserted into the implied path before the arc and the path is + closed back to the, center forming a wedge. Otherwise, the implied path + contains just the arc and is not closed. + @param oval The bounds of oval used to define the shape of the arc. @param startAngle Starting angle (in degrees) where the arc begins - @param sweepAngle Sweep angle (in degrees) measured clockwise - @param useCenter true means include the center of the oval. For filling - this will draw a wedge. False means just use the arc. + @param sweepAngle Sweep angle (in degrees) measured clockwise. + @param useCenter true means include the center of the oval. @param paint The paint used to draw the arc */ void drawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle, @@ -665,7 +799,106 @@ class SK_API SkCanvas : public SkRefCnt { @param path The path to be drawn @param paint The paint used to draw the path */ - virtual void drawPath(const SkPath& path, const SkPaint& paint); + void drawPath(const SkPath& path, const SkPaint& paint); + + /** Draw the specified image, with its top/left corner at (x,y), using the + specified paint, transformed by the current matrix. + + @param image The image to be drawn + @param left The position of the left side of the image being drawn + @param top The position of the top side of the image being drawn + @param paint The paint used to draw the image, or NULL + */ + void drawImage(const SkImage* image, SkScalar left, SkScalar top, const SkPaint* paint = NULL); + void drawImage(const sk_sp& image, SkScalar left, SkScalar top, + const SkPaint* paint = NULL) { + this->drawImage(image.get(), left, top, paint); + } + + /** + * Controls the behavior at the edge of the src-rect, when specified in drawImageRect, + * trading off speed for exactness. + * + * When filtering is enabled (in the Paint), skia may need to sample in a neighborhood around + * the pixels in the image. If there is a src-rect specified, it is intended to restrict the + * pixels that will be read. However, for performance reasons, some implementations may slow + * down if they cannot read 1-pixel past the src-rect boundary at times. + * + * This enum allows the caller to specify if such a 1-pixel "slop" will be visually acceptable. + * If it is, the caller should pass kFast, and it may result in a faster draw. If the src-rect + * must be strictly respected, the caller should pass kStrict. + */ + enum SrcRectConstraint { + /** + * If kStrict is specified, the implementation must respect the src-rect + * (if specified) strictly, and will never sample outside of those bounds during sampling + * even when filtering. This may be slower than kFast. + */ + kStrict_SrcRectConstraint, + + /** + * If kFast is specified, the implementation may sample outside of the src-rect + * (if specified) by half the width of filter. This allows greater flexibility + * to the implementation and can make the draw much faster. + */ + kFast_SrcRectConstraint, + }; + + /** Draw the specified image, scaling and translating so that it fills the specified + * dst rect. If the src rect is non-null, only that subset of the image is transformed + * and drawn. + * + * @param image The image to be drawn + * @param src Optional: specify the subset of the image to be drawn + * @param dst The destination rectangle where the scaled/translated + * image will be drawn + * @param paint The paint used to draw the image, or NULL + * @param constraint Control the tradeoff between speed and exactness w.r.t. the src-rect. + */ + void drawImageRect(const SkImage* image, const SkRect& src, const SkRect& dst, + const SkPaint* paint, + SrcRectConstraint constraint = kStrict_SrcRectConstraint); + // variant that takes src SkIRect + void drawImageRect(const SkImage* image, const SkIRect& isrc, const SkRect& dst, + const SkPaint* paint, SrcRectConstraint = kStrict_SrcRectConstraint); + // variant that assumes src == image-bounds + void drawImageRect(const SkImage* image, const SkRect& dst, const SkPaint* paint, + SrcRectConstraint = kStrict_SrcRectConstraint); + + void drawImageRect(const sk_sp& image, const SkRect& src, const SkRect& dst, + const SkPaint* paint, + SrcRectConstraint constraint = kStrict_SrcRectConstraint) { + this->drawImageRect(image.get(), src, dst, paint, constraint); + } + void drawImageRect(const sk_sp& image, const SkIRect& isrc, const SkRect& dst, + const SkPaint* paint, SrcRectConstraint cons = kStrict_SrcRectConstraint) { + this->drawImageRect(image.get(), isrc, dst, paint, cons); + } + void drawImageRect(const sk_sp& image, const SkRect& dst, const SkPaint* paint, + SrcRectConstraint cons = kStrict_SrcRectConstraint) { + this->drawImageRect(image.get(), dst, paint, cons); + } + + /** + * Draw the image stretched differentially to fit into dst. + * center is a rect within the image, and logically divides the image + * into 9 sections (3x3). For example, if the middle pixel of a [5x5] + * image is the "center", then the center-rect should be [2, 2, 3, 3]. + * + * If the dst is >= the image size, then... + * - The 4 corners are not stretched at all. + * - The sides are stretched in only one axis. + * - The center is stretched in both axes. + * Else, for each axis where dst < image, + * - The corners shrink proportionally + * - The sides (along the shrink axis) and center are not drawn + */ + void drawImageNine(const SkImage*, const SkIRect& center, const SkRect& dst, + const SkPaint* paint = nullptr); + void drawImageNine(const sk_sp& image, const SkIRect& center, const SkRect& dst, + const SkPaint* paint = nullptr) { + this->drawImageNine(image.get(), center, dst, paint); + } /** Draw the specified bitmap, with its top/left corner at (x,y), using the specified paint, transformed by the current matrix. Note: if the paint @@ -675,7 +908,7 @@ class SK_API SkCanvas : public SkRefCnt { width/height will be the edge color replicated. If a shader is present on the paint it will be ignored, except in the - case where the bitmap is kA8_Config. In that case, the color is + case where the bitmap is kAlpha_8_SkColorType. In that case, the color is generated by the shader. @param bitmap The bitmap to be drawn @@ -683,54 +916,30 @@ class SK_API SkCanvas : public SkRefCnt { @param top The position of the top side of the bitmap being drawn @param paint The paint used to draw the bitmap, or NULL */ - virtual void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top, - const SkPaint* paint = NULL); - - enum DrawBitmapRectFlags { - kNone_DrawBitmapRectFlag = 0x0, - /** - * When filtering is enabled, allow the color samples outside of - * the src rect (but still in the src bitmap) to bleed into the - * drawn portion - */ - kBleed_DrawBitmapRectFlag = 0x1, - }; - - /** Draw the specified bitmap, with the specified matrix applied (before the - canvas' matrix is applied). - @param bitmap The bitmap to be drawn - @param src Optional: specify the subset of the bitmap to be drawn - @param dst The destination rectangle where the scaled/translated - image will be drawn - @param paint The paint used to draw the bitmap, or NULL - */ - virtual void drawBitmapRectToRect(const SkBitmap& bitmap, const SkRect* src, - const SkRect& dst, - const SkPaint* paint = NULL, - DrawBitmapRectFlags flags = kNone_DrawBitmapRectFlag); - - void drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst, - const SkPaint* paint = NULL) { - this->drawBitmapRectToRect(bitmap, NULL, dst, paint, kNone_DrawBitmapRectFlag); - } - - void drawBitmapRect(const SkBitmap& bitmap, const SkIRect* isrc, - const SkRect& dst, const SkPaint* paint = NULL, - DrawBitmapRectFlags flags = kNone_DrawBitmapRectFlag) { - SkRect realSrcStorage; - SkRect* realSrcPtr = NULL; - if (isrc) { - realSrcStorage.set(*isrc); - realSrcPtr = &realSrcStorage; - } - this->drawBitmapRectToRect(bitmap, realSrcPtr, dst, paint, flags); - } + void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top, + const SkPaint* paint = NULL); - virtual void drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m, - const SkPaint* paint = NULL); + /** Draw the specified bitmap, scaling and translating so that it fills the specified + * dst rect. If the src rect is non-null, only that subset of the bitmap is transformed + * and drawn. + * + * @param bitmap The bitmap to be drawn + * @param src Optional: specify the subset of the bitmap to be drawn + * @param dst The destination rectangle where the scaled/translated + * bitmap will be drawn + * @param paint The paint used to draw the bitmap, or NULL + * @param constraint Control the tradeoff between speed and exactness w.r.t. the src-rect. + */ + void drawBitmapRect(const SkBitmap& bitmap, const SkRect& src, const SkRect& dst, + const SkPaint* paint, SrcRectConstraint = kStrict_SrcRectConstraint); + // variant where src is SkIRect + void drawBitmapRect(const SkBitmap& bitmap, const SkIRect& isrc, const SkRect& dst, + const SkPaint* paint, SrcRectConstraint = kStrict_SrcRectConstraint); + void drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst, const SkPaint* paint, + SrcRectConstraint = kStrict_SrcRectConstraint); /** - * Draw the bitmap stretched differentially to fit into dst. + * Draw the bitmap stretched or shrunk differentially to fit into dst. * center is a rect within the bitmap, and logically divides the bitmap * into 9 sections (3x3). For example, if the middle pixel of a [5x5] * bitmap is the "center", then the center-rect should be [2, 2, 3, 3]. @@ -743,22 +952,71 @@ class SK_API SkCanvas : public SkRefCnt { * - The corners shrink proportionally * - The sides (along the shrink axis) and center are not drawn */ - virtual void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, - const SkRect& dst, const SkPaint* paint = NULL); + void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst, + const SkPaint* paint = NULL); - /** Draw the specified bitmap, with its top/left corner at (x,y), - NOT transformed by the current matrix. Note: if the paint - contains a maskfilter that generates a mask which extends beyond the - bitmap's original width/height, then the bitmap will be drawn as if it - were in a Shader with CLAMP mode. Thus the color outside of the original - width/height will be the edge color replicated. - @param bitmap The bitmap to be drawn - @param left The position of the left side of the bitmap being drawn - @param top The position of the top side of the bitmap being drawn - @param paint The paint used to draw the bitmap, or NULL - */ - virtual void drawSprite(const SkBitmap& bitmap, int left, int top, - const SkPaint* paint = NULL); + /** + * Specifies coordinates to divide a bitmap into (xCount*yCount) rects. + * + * If the lattice divs or bounds are invalid, the entire lattice + * struct will be ignored on the draw call. + */ + struct Lattice { + enum Flags : uint8_t { + // If set, indicates that we should not draw corresponding rect. + kTransparent_Flags = 1 << 0, + }; + + // An array of x-coordinates that divide the bitmap vertically. + // These must be unique, increasing, and in the set [fBounds.fLeft, fBounds.fRight). + // Does not have ownership. + const int* fXDivs; + + // An array of y-coordinates that divide the bitmap horizontally. + // These must be unique, increasing, and in the set [fBounds.fTop, fBounds.fBottom). + // Does not have ownership. + const int* fYDivs; + + // If non-null, the length of this array must be equal to + // (fXCount + 1) * (fYCount + 1). Note that we allow the first rect + // in each direction to be empty (ex: fXDivs[0] = fBounds.fLeft). + // In this case, the caller still must specify a flag (as a placeholder) + // for these empty rects. + // The flags correspond to the rects in the lattice, first moving + // left to right and then top to bottom. + const Flags* fFlags; + + // The number of fXDivs. + int fXCount; + + // The number of fYDivs. + int fYCount; + + // The bound to draw from. Must be contained by the src that is being drawn, + // non-empty, and non-inverted. + // If nullptr, the bounds are the entire src. + const SkIRect* fBounds; + }; + + /** + * Draw the bitmap stretched or shrunk differentially to fit into dst. + * + * Moving horizontally across the bitmap, alternating rects will be "scalable" + * (in the x-dimension) to fit into dst or must be left "fixed". The first rect + * is treated as "fixed", but it's possible to specify an empty first rect by + * making lattice.fXDivs[0] = 0. + * + * The scale factor for all "scalable" rects will be the same, and may be greater + * than or less than 1 (meaning we can stretch or shrink). If the number of + * "fixed" pixels is greater than the width of the dst, we will collapse all of + * the "scalable" regions and appropriately downscale the "fixed" regions. + * + * The same interpretation also applies to the y-dimension. + */ + void drawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice, const SkRect& dst, + const SkPaint* paint = nullptr); + void drawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst, + const SkPaint* paint = nullptr); /** Draw the text, with origin at (x,y), using the specified paint. The origin is interpreted based on the Align setting in the paint. @@ -768,8 +1026,8 @@ class SK_API SkCanvas : public SkRefCnt { @param y The y-coordinate of the origin of the text being drawn @param paint The paint used for the text (e.g. color, size, style) */ - virtual void drawText(const void* text, size_t byteLength, SkScalar x, - SkScalar y, const SkPaint& paint); + void drawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, + const SkPaint& paint); /** Draw the text, with each character/glyph origin specified by the pos[] array. The origin is interpreted by the Align setting in the paint. @@ -778,8 +1036,8 @@ class SK_API SkCanvas : public SkRefCnt { @param pos Array of positions, used to position each character @param paint The paint used for the text (e.g. color, size, style) */ - virtual void drawPosText(const void* text, size_t byteLength, - const SkPoint pos[], const SkPaint& paint); + void drawPosText(const void* text, size_t byteLength, const SkPoint pos[], + const SkPaint& paint); /** Draw the text, with each character/glyph origin specified by the x coordinate taken from the xpos[] array, and the y from the constY param. @@ -790,9 +1048,8 @@ class SK_API SkCanvas : public SkRefCnt { @param constY The shared Y coordinate for all of the positions @param paint The paint used for the text (e.g. color, size, style) */ - virtual void drawPosTextH(const void* text, size_t byteLength, - const SkScalar xpos[], SkScalar constY, - const SkPaint& paint); + void drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY, + const SkPaint& paint); /** Draw the text, with origin at (x,y), using the specified paint, along the specified path. The paint's Align setting determins where along the @@ -806,8 +1063,7 @@ class SK_API SkCanvas : public SkRefCnt { position the text @param paint The paint used for the text */ - void drawTextOnPathHV(const void* text, size_t byteLength, - const SkPath& path, SkScalar hOffset, + void drawTextOnPathHV(const void* text, size_t byteLength, const SkPath& path, SkScalar hOffset, SkScalar vOffset, const SkPaint& paint); /** Draw the text, with origin at (x,y), using the specified paint, along @@ -820,9 +1076,27 @@ class SK_API SkCanvas : public SkRefCnt { mapped onto the path @param paint The paint used for the text */ - virtual void drawTextOnPath(const void* text, size_t byteLength, - const SkPath& path, const SkMatrix* matrix, - const SkPaint& paint); + void drawTextOnPath(const void* text, size_t byteLength, const SkPath& path, + const SkMatrix* matrix, const SkPaint& paint); + + /** + * Draw the text with each character/glyph individually transformed by its xform. + * If cullRect is not null, it is a conservative bounds of what will be drawn + * taking into account the xforms and the paint, and will be used to accelerate culling. + */ + void drawTextRSXform(const void* text, size_t byteLength, const SkRSXform[], + const SkRect* cullRect, const SkPaint& paint); + + /** Draw the text blob, offset by (x,y), using the specified paint. + @param blob The text blob to be drawn + @param x The x-offset of the text being drawn + @param y The y-offset of the text being drawn + @param paint The paint used for the text (e.g. color, size, style) + */ + void drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint); + void drawTextBlob(const sk_sp& blob, SkScalar x, SkScalar y, const SkPaint& paint) { + this->drawTextBlob(blob.get(), x, y, paint); + } /** Draw the picture into this canvas. This method effective brackets the playback of the picture's draw calls with save/restore, so the state @@ -830,7 +1104,76 @@ class SK_API SkCanvas : public SkRefCnt { @param picture The recorded drawing commands to playback into this canvas. */ - virtual void drawPicture(SkPicture& picture); + void drawPicture(const SkPicture* picture) { + this->drawPicture(picture, NULL, NULL); + } + void drawPicture(const sk_sp& picture) { + this->drawPicture(picture.get()); + } + + /** + * Draw the picture into this canvas. + * + * If matrix is non-null, apply that matrix to the CTM when drawing this picture. This is + * logically equivalent to + * save/concat/drawPicture/restore + * + * If paint is non-null, draw the picture into a temporary buffer, and then apply the paint's + * alpha/colorfilter/imagefilter/xfermode to that buffer as it is drawn to the canvas. + * This is logically equivalent to + * saveLayer(paint)/drawPicture/restore + */ + void drawPicture(const SkPicture*, const SkMatrix* matrix, const SkPaint* paint); + void drawPicture(const sk_sp& picture, const SkMatrix* matrix, const SkPaint* paint) { + this->drawPicture(picture.get(), matrix, paint); + } + +#ifdef SK_EXPERIMENTAL_SHADOWING + /** + * Draw the picture into this canvas, with shadows! + * + * We will use the canvas's lights along with the picture information (draw depths of + * objects, etc) to first create a set of shadowmaps for the light-picture pairs, and + * then use that set of shadowmaps to render the scene with shadows. + * + * If matrix is non-null, apply that matrix to the CTM when drawing this picture. This is + * logically equivalent to + * save/concat/drawPicture/restore + * + * If paint is non-null, draw the picture into a temporary buffer, and then apply the paint's + * alpha/colorfilter/imagefilter/xfermode to that buffer as it is drawn to the canvas. + * This is logically equivalent to + * saveLayer(paint)/drawPicture/restore + * + * We also support using variance shadow maps for blurred shadows; the user can specify + * what shadow mapping algorithm to use with params. + * - Variance Shadow Mapping works by storing both the depth and depth^2 in the shadow map. + * - Then, the shadow map can be blurred, and when reading from it, the fragment shader + * can calculate the variance of the depth at a position by doing E(x^2) - E(x)^2. + * - We can then use the depth variance and depth at a fragment to arrive at an upper bound + * of the probability that the current surface is shadowed by using Chebyshev's + * inequality, and then use that to shade the fragment. + * + * - There are a few problems with VSM. + * * Light Bleeding | Areas with high variance, such as near the edges of high up rects, + * will cause their shadow penumbras to overwrite otherwise solid + * shadows. + * * Shape Distortion | We can combat Light Bleeding by biasing the shadow (setting + * mostly shaded fragments to completely shaded) and increasing + * the minimum allowed variance. However, this warps and rounds + * out the shape of the shadow. + */ + void drawShadowedPicture(const SkPicture*, + const SkMatrix* matrix, + const SkPaint* paint, + const SkShadowParams& params); + void drawShadowedPicture(const sk_sp& picture, + const SkMatrix* matrix, + const SkPaint* paint, + const SkShadowParams& params) { + this->drawShadowedPicture(picture.get(), matrix, paint, params); + } +#endif enum VertexMode { kTriangles_VertexMode, @@ -839,6 +1182,11 @@ class SK_API SkCanvas : public SkRefCnt { }; /** Draw the array of vertices, interpreted as triangles (based on mode). + + If both textures and vertex-colors are NULL, it strokes hairlines with + the paint's color. This behavior is a useful debugging mode to visualize + the mesh. + @param vmode How to interpret the array of vertices @param vertexCount The number of points in the vertices array (and corresponding texs and colors arrays if non-null) @@ -847,71 +1195,121 @@ class SK_API SkCanvas : public SkRefCnt { in _texture_ space (not uv space) for each vertex. @param colors May be null. If not null, specifies a color for each vertex, to be interpolated across the triangle. - @param xmode Used if both texs and colors are present. In this + @param mode Used if both texs and colors are present. In this case the colors are combined with the texture using mode, - before being drawn using the paint. If mode is null, then - kModulate_Mode is used. + before being drawn using the paint. @param indices If not null, array of indices to reference into the vertex (texs, colors) array. @param indexCount number of entries in the indices array (if not null) @param paint Specifies the shader/texture if present. */ - virtual void drawVertices(VertexMode vmode, int vertexCount, - const SkPoint vertices[], const SkPoint texs[], - const SkColor colors[], SkXfermode* xmode, - const uint16_t indices[], int indexCount, - const SkPaint& paint); - - /** Send a blob of data to the canvas. - For canvases that draw, this call is effectively a no-op, as the data - is not parsed, but just ignored. However, this call exists for - subclasses like SkPicture's recording canvas, that can store the data - and then play it back later (via another call to drawData). + void drawVertices(VertexMode vmode, int vertexCount, + const SkPoint vertices[], const SkPoint texs[], + const SkColor colors[], SkBlendMode mode, + const uint16_t indices[], int indexCount, + const SkPaint& paint); + void drawVertices(VertexMode vmode, int vertexCount, + const SkPoint vertices[], const SkPoint texs[], + const SkColor colors[], const uint16_t indices[], int indexCount, + const SkPaint& paint) { + this->drawVertices(vmode, vertexCount, vertices, texs, colors, SkBlendMode::kModulate, + indices, indexCount, paint); + } + + /** + Draw a cubic coons patch + + @param cubic specifies the 4 bounding cubic bezier curves of a patch with clockwise order + starting at the top left corner. + @param colors specifies the colors for the corners which will be bilerp across the patch, + their order is clockwise starting at the top left corner. + @param texCoords specifies the texture coordinates that will be bilerp across the patch, + their order is the same as the colors. + @param mode specifies how are the colors and the textures combined if both of them are + present. + @param paint Specifies the shader/texture if present. */ - virtual void drawData(const void* data, size_t length) { - // do nothing. Subclasses may do something with the data + void drawPatch(const SkPoint cubics[12], const SkColor colors[4], + const SkPoint texCoords[4], SkBlendMode mode, const SkPaint& paint); + void drawPatch(const SkPoint cubics[12], const SkColor colors[4], + const SkPoint texCoords[4], const SkPaint& paint) { + this->drawPatch(cubics, colors, texCoords, SkBlendMode::kModulate, paint); } - - // MM-2013-08-16: [[ RefactorGraphics ]] Expose drawDevMask. Used to render masks produced by platform specific text rendering procedures. - virtual void drawDevMask(SkMask& mask, const SkPaint&); - /** Add comments. beginCommentGroup/endCommentGroup open/close a new group. - Each comment added via addComment is notionally attached to its - enclosing group. Top-level comments simply belong to no group. + /** + * Draw a set of sprites from the atlas. Each is specified by a tex rectangle in the + * coordinate space of the atlas, and a corresponding xform which transforms the tex rectangle + * into a quad. + * + * xform maps [0, 0, tex.width, tex.height] -> quad + * + * The color array is optional. When specified, each color modulates the pixels in its + * corresponding quad (via the specified SkBlendMode). + * + * The cullRect is optional. When specified, it must be a conservative bounds of all of the + * resulting transformed quads, allowing the canvas to skip drawing if the cullRect does not + * intersect the current clip. + * + * The paint is optional. If specified, its antialiasing, alpha, color-filter, image-filter + * and blendmode are used to affect each of the quads. */ - virtual void beginCommentGroup(const char* description) { - // do nothing. Subclasses may do something + void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], + const SkColor colors[], int count, SkBlendMode, const SkRect* cullRect, + const SkPaint* paint); + void drawAtlas(const sk_sp& atlas, const SkRSXform xform[], const SkRect tex[], + const SkColor colors[], int count, SkBlendMode mode, const SkRect* cullRect, + const SkPaint* paint) { + this->drawAtlas(atlas.get(), xform, tex, colors, count, mode, cullRect, paint); } - virtual void addComment(const char* kywd, const char* value) { - // do nothing. Subclasses may do something + void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], int count, + const SkRect* cullRect, const SkPaint* paint) { + this->drawAtlas(atlas, xform, tex, nullptr, count, SkBlendMode::kDst, cullRect, paint); } - virtual void endCommentGroup() { - // do nothing. Subclasses may do something + void drawAtlas(const sk_sp& atlas, const SkRSXform xform[], const SkRect tex[], + int count, const SkRect* cullRect, const SkPaint* paint) { + this->drawAtlas(atlas.get(), xform, tex, nullptr, count, SkBlendMode::kDst, + cullRect, paint); } + /** + * Draw the contents of this drawable into the canvas. If the canvas is async + * (e.g. it is recording into a picture) then the drawable will be referenced instead, + * to have its draw() method called when the picture is finalized. + * + * If the intent is to force the contents of the drawable into this canvas immediately, + * then drawable->draw(canvas) may be called. + */ + void drawDrawable(SkDrawable* drawable, const SkMatrix* = NULL); + void drawDrawable(SkDrawable*, SkScalar x, SkScalar y); - ////////////////////////////////////////////////////////////////////////// + /** + * Send an "annotation" to the canvas. The annotation is a key/value pair, where the key is + * a null-terminated utf8 string, and the value is a blob of data stored in an SkData + * (which may be null). The annotation is associated with the specified rectangle. + * + * The caller still retains its ownership of the data (if any). + * + * Note: on may canvas types, this information is ignored, but some canvases (e.g. recording + * a picture or drawing to a PDF document) will pass on this information. + */ + void drawAnnotation(const SkRect&, const char key[], SkData* value); + void drawAnnotation(const SkRect& rect, const char key[], const sk_sp& value) { + this->drawAnnotation(rect, key, value.get()); + } - /** Get the current bounder object. - The bounder's reference count is unchaged. - @return the canva's bounder (or NULL). - */ - SkBounder* getBounder() const { return fBounder; } - - /** Set a new bounder (or NULL). - Pass NULL to clear any previous bounder. - As a convenience, the parameter passed is also returned. - If a previous bounder exists, its reference count is decremented. - If bounder is not NULL, its reference count is incremented. - @param bounder the new bounder (or NULL) to be installed in the canvas - @return the set bounder object - */ - virtual SkBounder* setBounder(SkBounder* bounder); + ////////////////////////////////////////////////////////////////////////// +#ifdef SK_INTERNAL +#ifndef SK_SUPPORT_LEGACY_DRAWFILTER + #define SK_SUPPORT_LEGACY_DRAWFILTER +#endif +#endif +#ifdef SK_SUPPORT_LEGACY_DRAWFILTER /** Get the current filter object. The filter's reference count is not affected. The filter is saved/restored, just like the matrix and clip. @return the canvas' filter (or NULL). */ + SK_ATTR_EXTERNALLY_DEPRECATED("getDrawFilter use is deprecated") SkDrawFilter* getDrawFilter() const; /** Set the new filter (or NULL). Pass NULL to clear any existing filter. @@ -922,50 +1320,42 @@ class SK_API SkCanvas : public SkRefCnt { @param filter the new filter (or NULL) @return the new filter */ + SK_ATTR_EXTERNALLY_DEPRECATED("setDrawFilter use is deprecated") virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter); - +#endif ////////////////////////////////////////////////////////////////////////// + /** + * Return true if the current clip is empty (i.e. nothing will draw). + * Note: this is not always a free call, so it should not be used + * more often than necessary. However, once the canvas has computed this + * result, subsequent calls will be cheap (until the clip state changes, + * which can happen on any clip..() or restore() call. + */ + virtual bool isClipEmpty() const; + + /** + * Returns true if the current clip is just a (non-empty) rectangle. + * Returns false if the clip is empty, or if it is complex. + */ + virtual bool isClipRect() const; + /** Return the current matrix on the canvas. This does not account for the translate in any of the devices. @return The current matrix on the canvas. */ const SkMatrix& getTotalMatrix() const; - enum ClipType { - kEmpty_ClipType = 0, - kRect_ClipType, - kComplex_ClipType - }; - - /** Returns a description of the total clip; may be cheaper than - getting the clip and querying it directly. - */ - ClipType getClipType() const; - - /** DEPRECATED -- need to move this guy to private/friend - * Return the current device clip (concatenation of all clip calls). - * This does not account for the translate in any of the devices. - * @return the current device clip (concatenation of all clip calls). - */ - const SkRegion& getTotalClip() const; - /** Return the clip stack. The clip stack stores all the individual * clips organized by the save/restore frame in which they were * added. * @return the current clip stack ("list" of individual clip elements) */ const SkClipStack* getClipStack() const { - return &fClipStack; + return fClipStack.get(); } - class ClipVisitor { - public: - virtual ~ClipVisitor(); - virtual void clipRect(const SkRect&, SkRegion::Op, bool antialias) = 0; - virtual void clipPath(const SkPath&, SkRegion::Op, bool antialias) = 0; - }; - + typedef SkCanvasClipVisitor ClipVisitor; /** * Replays the clip operations, back to front, that have been applied to * the canvas, calling the appropriate method on the visitor for each @@ -975,16 +1365,170 @@ class SK_API SkCanvas : public SkRefCnt { /////////////////////////////////////////////////////////////////////////// + // don't call + GrRenderTargetContext* internal_private_accessTopLayerRenderTargetContext(); + + // don't call + static void Internal_Private_SetIgnoreSaveLayerBounds(bool); + static bool Internal_Private_GetIgnoreSaveLayerBounds(); + static void Internal_Private_SetTreatSpriteAsBitmap(bool); + static bool Internal_Private_GetTreatSpriteAsBitmap(); + + // TEMP helpers until we switch virtual over to const& for src-rect + void legacy_drawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst, + const SkPaint* paint, + SrcRectConstraint constraint = kStrict_SrcRectConstraint); + void legacy_drawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst, + const SkPaint* paint, + SrcRectConstraint constraint = kStrict_SrcRectConstraint); + + // expose minimum amount of information necessary for transitional refactoring + /** + * Returns CTM and clip bounds, translated from canvas coordinates to top layer coordinates. + */ + void temporary_internal_describeTopLayer(SkMatrix* matrix, SkIRect* clip_bounds); + +protected: +#ifdef SK_EXPERIMENTAL_SHADOWING + /** Returns the current (cumulative) draw depth of the canvas. + */ + SkScalar getZ() const; + + sk_sp fLights; +#endif + + // default impl defers to getDevice()->newSurface(info) + virtual sk_sp onNewSurface(const SkImageInfo&, const SkSurfaceProps&); + + // default impl defers to its device + virtual bool onPeekPixels(SkPixmap*); + virtual bool onAccessTopLayerPixels(SkPixmap*); + virtual SkImageInfo onImageInfo() const; + virtual bool onGetProps(SkSurfaceProps*) const; + virtual void onFlush(); + + // Subclass save/restore notifiers. + // Overriders should call the corresponding INHERITED method up the inheritance chain. + // getSaveLayerStrategy()'s return value may suppress full layer allocation. + enum SaveLayerStrategy { + kFullLayer_SaveLayerStrategy, + kNoLayer_SaveLayerStrategy, + }; + + virtual void willSave() {} + // Overriders should call the corresponding INHERITED method up the inheritance chain. + virtual SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec&) { + return kFullLayer_SaveLayerStrategy; + } + virtual void willRestore() {} + virtual void didRestore() {} + virtual void didConcat(const SkMatrix&) {} + virtual void didSetMatrix(const SkMatrix&) {} + virtual void didTranslate(SkScalar dx, SkScalar dy) { + this->didConcat(SkMatrix::MakeTrans(dx, dy)); + } + +#ifdef SK_EXPERIMENTAL_SHADOWING + virtual void didTranslateZ(SkScalar) {} +#endif + + virtual void onDrawAnnotation(const SkRect&, const char key[], SkData* value); + virtual void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&); + + virtual void onDrawText(const void* text, size_t byteLength, SkScalar x, + SkScalar y, const SkPaint& paint); + + virtual void onDrawPosText(const void* text, size_t byteLength, + const SkPoint pos[], const SkPaint& paint); + + virtual void onDrawPosTextH(const void* text, size_t byteLength, + const SkScalar xpos[], SkScalar constY, + const SkPaint& paint); + + virtual void onDrawTextOnPath(const void* text, size_t byteLength, + const SkPath& path, const SkMatrix* matrix, + const SkPaint& paint); + virtual void onDrawTextRSXform(const void* text, size_t byteLength, const SkRSXform[], + const SkRect* cullRect, const SkPaint& paint); + + virtual void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, + const SkPaint& paint); + + virtual void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4], + const SkPoint texCoords[4], SkBlendMode, const SkPaint& paint); + + virtual void onDrawDrawable(SkDrawable*, const SkMatrix*); + + virtual void onDrawPaint(const SkPaint&); + virtual void onDrawRect(const SkRect&, const SkPaint&); + virtual void onDrawRegion(const SkRegion& region, const SkPaint& paint); + virtual void onDrawOval(const SkRect&, const SkPaint&); + virtual void onDrawArc(const SkRect&, SkScalar startAngle, SkScalar sweepAngle, bool useCenter, + const SkPaint&); + virtual void onDrawRRect(const SkRRect&, const SkPaint&); + virtual void onDrawPoints(PointMode, size_t count, const SkPoint pts[], const SkPaint&); + virtual void onDrawVertices(VertexMode, int vertexCount, const SkPoint vertices[], + const SkPoint texs[], const SkColor colors[], SkBlendMode, + const uint16_t indices[], int indexCount, const SkPaint&); + + virtual void onDrawAtlas(const SkImage*, const SkRSXform[], const SkRect[], const SkColor[], + int count, SkBlendMode, const SkRect* cull, const SkPaint*); + virtual void onDrawPath(const SkPath&, const SkPaint&); + virtual void onDrawImage(const SkImage*, SkScalar dx, SkScalar dy, const SkPaint*); + virtual void onDrawImageRect(const SkImage*, const SkRect*, const SkRect&, const SkPaint*, + SrcRectConstraint); + virtual void onDrawImageNine(const SkImage*, const SkIRect& center, const SkRect& dst, + const SkPaint*); + virtual void onDrawImageLattice(const SkImage*, const Lattice& lattice, const SkRect& dst, + const SkPaint*); + + virtual void onDrawBitmap(const SkBitmap&, SkScalar dx, SkScalar dy, const SkPaint*); + virtual void onDrawBitmapRect(const SkBitmap&, const SkRect*, const SkRect&, const SkPaint*, + SrcRectConstraint); + virtual void onDrawBitmapNine(const SkBitmap&, const SkIRect& center, const SkRect& dst, + const SkPaint*); + virtual void onDrawBitmapLattice(const SkBitmap&, const Lattice& lattice, const SkRect& dst, + const SkPaint*); + + enum ClipEdgeStyle { + kHard_ClipEdgeStyle, + kSoft_ClipEdgeStyle + }; + + virtual void onClipRect(const SkRect& rect, ClipOp, ClipEdgeStyle); + virtual void onClipRRect(const SkRRect& rrect, ClipOp, ClipEdgeStyle); + virtual void onClipPath(const SkPath& path, ClipOp, ClipEdgeStyle); + virtual void onClipRegion(const SkRegion& deviceRgn, ClipOp); + + virtual void onDiscard(); + + virtual void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*); + +#ifdef SK_EXPERIMENTAL_SHADOWING + virtual void onDrawShadowedPicture(const SkPicture*, + const SkMatrix*, + const SkPaint*, + const SkShadowParams& params); +#endif + + // Clip rectangle bounds. Called internally by saveLayer. + // returns false if the entire rectangle is entirely clipped out + // If non-NULL, The imageFilter parameter will be used to expand the clip + // and offscreen bounds for any margin required by the filter DAG. + bool clipRectBounds(const SkRect* bounds, SaveLayerFlags, SkIRect* intersection, + const SkImageFilter* imageFilter = NULL); + +private: /** After calling saveLayer(), there can be any number of devices that make - up the top-most drawing area. LayerIter can be used to iterate through - those devices. Note that the iterator is only valid until the next API - call made on the canvas. Ownership of all pointers in the iterator stays - with the canvas, so none of them should be modified or deleted. - */ - class SK_API LayerIter /*: SkNoncopyable*/ { + up the top-most drawing area. LayerIter can be used to iterate through + those devices. Note that the iterator is only valid until the next API + call made on the canvas. Ownership of all pointers in the iterator stays + with the canvas, so none of them should be modified or deleted. + */ + class LayerIter /*: SkNoncopyable*/ { public: /** Initialize iterator with canvas, and set values for 1st device */ - LayerIter(SkCanvas*, bool skipEmptyClips); + LayerIter(SkCanvas*); ~LayerIter(); /** Return true if the iterator is done */ @@ -996,7 +1540,7 @@ class SK_API SkCanvas : public SkRefCnt { SkBaseDevice* device() const; const SkMatrix& matrix() const; - const SkRegion& clip() const; + const SkRasterClip& clip() const; const SkPaint& paint() const; int x() const; int y() const; @@ -1013,50 +1557,46 @@ class SK_API SkCanvas : public SkRefCnt { bool fDone; }; -protected: - // Returns the canvas to be used by DrawIter. Default implementation - // returns this. Subclasses that encapsulate an indirect canvas may - // need to overload this method. The impl must keep track of this, as it - // is not released or deleted by the caller. - virtual SkCanvas* canvasForDrawIter(); + static bool BoundsAffectsClip(SaveLayerFlags); + static SaveLayerFlags LegacySaveFlagsToSaveLayerFlags(uint32_t legacySaveFlags); - // Clip rectangle bounds. Called internally by saveLayer. - // returns false if the entire rectangle is entirely clipped out - bool clipRectBounds(const SkRect* bounds, SaveFlags flags, - SkIRect* intersection); + static void DrawDeviceWithFilter(SkBaseDevice* src, const SkImageFilter* filter, + SkBaseDevice* dst, const SkMatrix& ctm, + const SkClipStack* clipStack); - // Called by child classes that override clipPath and clipRRect to only - // track fast conservative clip bounds, rather than exact clips. - bool updateClipConservativelyUsingBounds(const SkRect&, SkRegion::Op, - bool inverseFilled); + enum ShaderOverrideOpacity { + kNone_ShaderOverrideOpacity, //!< there is no overriding shader (bitmap or image) + kOpaque_ShaderOverrideOpacity, //!< the overriding shader is opaque + kNotOpaque_ShaderOverrideOpacity, //!< the overriding shader may not be opaque + }; // notify our surface (if we have one) that we are about to draw, so it // can perform copy-on-write or invalidate any cached images - void predrawNotify(); - - /** - DEPRECATED -- need to remove when subclass stop relying on it. - Marked as 'protected' to avoid new clients using this before we can - completely remove it. - - Specify a device for this canvas to draw into. If it is not null, its - reference count is incremented. If the canvas was already holding a - device, its reference count is decremented. The new device is returned. - */ - virtual SkBaseDevice* setDevice(SkBaseDevice* device); + void predrawNotify(bool willOverwritesEntireSurface = false); + void predrawNotify(const SkRect* rect, const SkPaint* paint, ShaderOverrideOpacity); + void predrawNotify(const SkRect* rect, const SkPaint* paint, bool shaderOverrideIsOpaque) { + this->predrawNotify(rect, paint, shaderOverrideIsOpaque ? kOpaque_ShaderOverrideOpacity + : kNotOpaque_ShaderOverrideOpacity); + } -private: class MCRec; - SkClipStack fClipStack; + sk_sp fClipStack; SkDeque fMCStack; // points to top of stack MCRec* fMCRec; // the first N recs that can fit here mean we won't call malloc - uint32_t fMCRecStorage[32]; + enum { + kMCRecSize = 128, // most recent measurement + kMCRecCount = 32, // common depth for save/restores + kDeviceCMSize = 176, // most recent measurement + }; + intptr_t fMCRecStorage[kMCRecSize * kMCRecCount / sizeof(intptr_t)]; + intptr_t fDeviceCMStorage[kDeviceCMSize / sizeof(intptr_t)]; + + const SkSurfaceProps fProps; - SkBounder* fBounder; - int fSaveLayerCount; // number of successful saveLayer calls + int fSaveCount; // value returned by getSaveCount() SkMetaData* fMetaData; @@ -1071,29 +1611,60 @@ class SK_API SkCanvas : public SkRefCnt { bool fDeviceCMDirty; // cleared by updateDeviceCMCache() void updateDeviceCMCache(); - friend class SkDrawIter; // needs setupDrawForLayerDevice() + void doSave(); + void checkForDeferredSave(); + void internalSetMatrix(const SkMatrix&); + + friend class SkDrawIter; // needs setupDrawForLayerDevice() friend class AutoDrawLooper; + friend class SkLua; // needs top layer size and offset + friend class SkDebugCanvas; // needs experimental fAllowSimplifyClip + friend class SkSurface_Raster; // needs getDevice() + friend class SkRecorder; // InitFlags + friend class SkLiteRecorder; // InitFlags + friend class SkNoDrawCanvas; // InitFlags + friend class SkNWayCanvas; // InitFlags + friend class SkPictureImageFilter; // SkCanvas(SkBaseDevice*, SkSurfaceProps*, InitFlags) + friend class SkPictureRecord; // predrawNotify (why does it need it? ) + friend class SkPicturePlayback; // SaveFlagsToSaveLayerFlags + friend class SkPipeCanvas; // InitFlags + friend class SkDeferredCanvas; // For use of resetForNextPicture + friend class SkOverdrawCanvas; + + enum InitFlags { + kDefault_InitFlags = 0, + kConservativeRasterClip_InitFlag = 1 << 0, + }; + SkCanvas(const SkIRect& bounds, InitFlags); + SkCanvas(SkBaseDevice* device, InitFlags); + + void resetForNextPicture(const SkIRect& bounds); - SkBaseDevice* createLayerDevice(SkBitmap::Config, int width, int height, - bool isOpaque); + // needs gettotalclip() + friend class SkCanvasStateUtils; - SkBaseDevice* init(SkBaseDevice*); + // call this each time we attach ourselves to a device + // - constructor + // - internalSaveLayer + void setupDevice(SkBaseDevice*); + + SkBaseDevice* init(SkBaseDevice*, InitFlags); + + /** + * Gets the bounds of the top level layer in global canvas coordinates. We don't want this + * to be public because it exposes decisions about layer sizes that are internal to the canvas. + */ + SkIRect getTopLayerBounds() const; - // internal methods are not virtual, so they can safely be called by other - // canvas apis, without confusing subclasses (like SkPictureRecording) - void internalDrawBitmap(const SkBitmap&, const SkMatrix& m, const SkPaint* paint); void internalDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst, const SkPaint* paint, - DrawBitmapRectFlags flags); - void internalDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, - const SkRect& dst, const SkPaint* paint); + SrcRectConstraint); void internalDrawPaint(const SkPaint& paint); - int internalSaveLayer(const SkRect* bounds, const SkPaint* paint, - SaveFlags, bool justForImageFilter); + void internalSaveLayer(const SaveLayerRec&, SaveLayerStrategy); void internalDrawDevice(SkBaseDevice*, int x, int y, const SkPaint*); // shared by save() and saveLayer() - int internalSave(SaveFlags flags); + void internalSave(); void internalRestore(); static void DrawRect(const SkDraw& draw, const SkPaint& paint, const SkRect& r, SkScalar textSize); @@ -1101,23 +1672,32 @@ class SK_API SkCanvas : public SkRefCnt { const char text[], size_t byteLength, SkScalar x, SkScalar y); - /* These maintain a cache of the clip bounds in local coordinates, - (converted to 2s-compliment if floats are slow). + // only for canvasutils + const SkRegion& internal_private_getTotalClip() const; + + /* + * Returns true if drawing the specified rect (or all if it is null) with the specified + * paint (or default if null) would overwrite the entire root device of the canvas + * (i.e. the canvas' surface if it had one). */ - mutable SkRect fCachedLocalClipBounds; - mutable bool fCachedLocalClipBoundsDirty; + bool wouldOverwriteEntireSurface(const SkRect*, const SkPaint*, ShaderOverrideOpacity) const; + + /** + * Returns true if the paint's imagefilter can be invoked directly, without needed a layer. + */ + bool canDrawBitmapAsSprite(SkScalar x, SkScalar y, int w, int h, const SkPaint&); + + + /** + * Keep track of the device clip bounds and if the matrix is scale-translate. This allows + * us to do a fast quick reject in the common case. + */ + bool fIsScaleTranslate; + SkRect fDeviceClipBounds; + bool fAllowSoftClip; bool fAllowSimplifyClip; - - const SkRect& getLocalClipBounds() const { - if (fCachedLocalClipBoundsDirty) { - if (!this->getClipBounds(&fCachedLocalClipBounds)) { - fCachedLocalClipBounds.setEmpty(); - } - fCachedLocalClipBoundsDirty = false; - } - return fCachedLocalClipBounds; - } + const bool fConservativeRasterClip; class AutoValidateClip : ::SkNoncopyable { public: @@ -1176,26 +1756,12 @@ class SkAutoCanvasRestore : SkNoncopyable { }; #define SkAutoCanvasRestore(...) SK_REQUIRE_LOCAL_VAR(SkAutoCanvasRestore) -/** Stack helper class to automatically open and close a comment block - */ -class SkAutoCommentBlock : SkNoncopyable { +class SkCanvasClipVisitor { public: - SkAutoCommentBlock(SkCanvas* canvas, const char* description) { - fCanvas = canvas; - if (NULL != fCanvas) { - fCanvas->beginCommentGroup(description); - } - } - - ~SkAutoCommentBlock() { - if (NULL != fCanvas) { - fCanvas->endCommentGroup(); - } - } - -private: - SkCanvas* fCanvas; + virtual ~SkCanvasClipVisitor(); + virtual void clipRect(const SkRect&, SkCanvas::ClipOp, bool antialias) = 0; + virtual void clipRRect(const SkRRect&, SkCanvas::ClipOp, bool antialias) = 0; + virtual void clipPath(const SkPath&, SkCanvas::ClipOp, bool antialias) = 0; }; -#define SkAutoCommentBlock(...) SK_REQUIRE_LOCAL_VAR(SkAutoCommentBlock) #endif diff --git a/libskia/include/core/SkChecksum.h b/libskia/include/core/SkChecksum.h deleted file mode 100644 index bf3228f9..00000000 --- a/libskia/include/core/SkChecksum.h +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright 2012 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef SkChecksum_DEFINED -#define SkChecksum_DEFINED - -#include "SkTypes.h" - -/** - * Computes a 32bit checksum from a blob of 32bit aligned data. This is meant - * to be very very fast, as it is used internally by the font cache, in - * conjuction with the entire raw key. This algorithm does not generate - * unique values as well as others (e.g. MD5) but it performs much faster. - * Skia's use cases can survive non-unique values (since the entire key is - * always available). Clients should only be used in circumstances where speed - * over uniqueness is at a premium. - */ -class SkChecksum : SkNoncopyable { -private: - /* - * Our Rotate and Mash helpers are meant to automatically do the right - * thing depending if sizeof(uintptr_t) is 4 or 8. - */ - enum { - ROTR = 17, - ROTL = sizeof(uintptr_t) * 8 - ROTR, - HALFBITS = sizeof(uintptr_t) * 4 - }; - - static inline uintptr_t Mash(uintptr_t total, uintptr_t value) { - return ((total >> ROTR) | (total << ROTL)) ^ value; - } - -public: - - /** - * Calculate 32-bit Murmur hash (murmur3). - * This should take 2-3x longer than SkChecksum::Compute, but is a considerably better hash. - * See en.wikipedia.org/wiki/MurmurHash. - * - * @param data Memory address of the data block to be processed. Must be 32-bit aligned. - * @param size Size of the data block in bytes. Must be a multiple of 4. - * @param seed Initial hash seed. (optional) - * @return hash result - */ - static uint32_t Murmur3(const uint32_t* data, size_t bytes, uint32_t seed=0) { - SkASSERT(SkIsAlign4(bytes)); - const size_t words = bytes/4; - - uint32_t hash = seed; - for (size_t i = 0; i < words; i++) { - uint32_t k = data[i]; - k *= 0xcc9e2d51; - k = (k << 15) | (k >> 17); - k *= 0x1b873593; - - hash ^= k; - hash = (hash << 13) | (hash >> 19); - hash *= 5; - hash += 0xe6546b64; - } - hash ^= bytes; - hash ^= hash >> 16; - hash *= 0x85ebca6b; - hash ^= hash >> 13; - hash *= 0xc2b2ae35; - hash ^= hash >> 16; - return hash; - } - - /** - * Compute a 32-bit checksum for a given data block - * - * WARNING: this algorithm is tuned for efficiency, not backward/forward - * compatibility. It may change at any time, so a checksum generated with - * one version of the Skia code may not match a checksum generated with - * a different version of the Skia code. - * - * @param data Memory address of the data block to be processed. Must be - * 32-bit aligned. - * @param size Size of the data block in bytes. Must be a multiple of 4. - * @return checksum result - */ - static uint32_t Compute(const uint32_t* data, size_t size) { - SkASSERT(SkIsAlign4(size)); - - /* - * We want to let the compiler use 32bit or 64bit addressing and math - * so we use uintptr_t as our magic type. This makes the code a little - * more obscure (we can't hard-code 32 or 64 anywhere, but have to use - * sizeof()). - */ - uintptr_t result = 0; - const uintptr_t* ptr = reinterpret_cast(data); - - /* - * count the number of quad element chunks. This takes into account - * if we're on a 32bit or 64bit arch, since we use sizeof(uintptr_t) - * to compute how much to shift-down the size. - */ - size_t n4 = size / (sizeof(uintptr_t) << 2); - for (size_t i = 0; i < n4; ++i) { - result = Mash(result, *ptr++); - result = Mash(result, *ptr++); - result = Mash(result, *ptr++); - result = Mash(result, *ptr++); - } - size &= ((sizeof(uintptr_t) << 2) - 1); - - data = reinterpret_cast(ptr); - const uint32_t* stop = data + (size >> 2); - while (data < stop) { - result = Mash(result, *data++); - } - - /* - * smash us down to 32bits if we were 64. Note that when uintptr_t is - * 32bits, this code-path should go away, but I still got a warning - * when I wrote - * result ^= result >> 32; - * since >>32 is undefined for 32bit ints, hence the wacky HALFBITS - * define. - */ - if (8 == sizeof(result)) { - result ^= result >> HALFBITS; - } - return static_cast(result); - } -}; - -#endif diff --git a/libskia/include/core/SkClipOp.h b/libskia/include/core/SkClipOp.h new file mode 100644 index 00000000..2e4fbbf8 --- /dev/null +++ b/libskia/include/core/SkClipOp.h @@ -0,0 +1,26 @@ +/* + * Copyright 2016 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkClipOp_DEFINED +#define SkClipOp_DEFINED + +#include "SkTypes.h" + +// these kept in SkRegion::Op order for now ... +enum SkClipOp { + kDifference_SkClipOp = 0, + kIntersect_SkClipOp = 1, + + // Goal: remove these, since they can grow the current clip + + kUnion_SkClipOp = 2, + kXOR_SkClipOp = 3, + kReverseDifference_SkClipOp = 4, + kReplace_SkClipOp = 5, +}; + +#endif diff --git a/libskia/include/core/SkClipStack.h b/libskia/include/core/SkClipStack.h index 8720005c..7a8eb5ca 100644 --- a/libskia/include/core/SkClipStack.h +++ b/libskia/include/core/SkClipStack.h @@ -1,19 +1,22 @@ - /* * Copyright 2011 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ + #ifndef SkClipStack_DEFINED #define SkClipStack_DEFINED +#include "SkCanvas.h" #include "SkDeque.h" #include "SkPath.h" #include "SkRect.h" +#include "SkRRect.h" #include "SkRegion.h" -#include "SkTDArray.h" +#include "SkTLazy.h" +class SkCanvasClipVisitor; // Because a single save/restore state can have multiple clips, this class // stores the stack depth (fSaveCount) and clips (fDeque) separately. @@ -21,7 +24,7 @@ // (i.e., the fSaveCount in force when it was added). Restores are thus // implemented by removing clips from fDeque that have an fSaveCount larger // then the freshly decremented count. -class SK_API SkClipStack { +class SK_API SkClipStack : public SkNVRefCnt { public: enum BoundsType { // The bounding box contains all the pixels that can be written to @@ -41,58 +44,63 @@ class SK_API SkClipStack { kEmpty_Type, //!< This element combines a rect with the current clip using a set operation kRect_Type, + //!< This element combines a round-rect with the current clip using a set operation + kRRect_Type, //!< This element combines a path with the current clip using a set operation kPath_Type, + + kLastType = kPath_Type }; + static const int kTypeCnt = kLastType + 1; Element() { - this->initCommon(0, SkRegion::kReplace_Op, false); + this->initCommon(0, SkCanvas::kReplace_Op, false); this->setEmpty(); } - Element(const SkRect& rect, SkRegion::Op op, bool doAA) { + Element(const Element&); + + Element(const SkRect& rect, SkCanvas::ClipOp op, bool doAA) { this->initRect(0, rect, op, doAA); } - Element(const SkPath& path, SkRegion::Op op, bool doAA) { - this->initPath(0, path, op, doAA); + Element(const SkRRect& rrect, SkCanvas::ClipOp op, bool doAA) { + this->initRRect(0, rrect, op, doAA); } - bool operator== (const Element& element) const { - if (this == &element) { - return true; - } - if (fOp != element.fOp || - fType != element.fType || - fDoAA != element.fDoAA || - fSaveCount != element.fSaveCount) { - return false; - } - switch (fType) { - case kPath_Type: - return fPath == element.fPath; - case kRect_Type: - return fRect == element.fRect; - case kEmpty_Type: - return true; - default: - SkDEBUGFAIL("Unexpected type."); - return false; - } + Element(const SkPath& path, SkCanvas::ClipOp op, bool doAA) { + this->initPath(0, path, op, doAA); } + + bool operator== (const Element& element) const; bool operator!= (const Element& element) const { return !(*this == element); } //!< Call to get the type of the clip element. Type getType() const { return fType; } + //!< Call to get the save count associated with this clip element. + int getSaveCount() const { return fSaveCount; } + //!< Call if getType() is kPath to get the path. - const SkPath& getPath() const { return fPath; } + const SkPath& getPath() const { SkASSERT(kPath_Type == fType); return *fPath.get(); } + + //!< Call if getType() is kRRect to get the round-rect. + const SkRRect& getRRect() const { SkASSERT(kRRect_Type == fType); return fRRect; } //!< Call if getType() is kRect to get the rect. - const SkRect& getRect() const { return fRect; } + const SkRect& getRect() const { + SkASSERT(kRect_Type == fType && (fRRect.isRect() || fRRect.isEmpty())); + return fRRect.getBounds(); + } //!< Call if getType() is not kEmpty to get the set operation used to combine this element. - SkRegion::Op getOp() const { return fOp; } + SkCanvas::ClipOp getOp() const { return fOp; } + + //!< Call to get the element as a path, regardless of its type. + void asPath(SkPath* path) const; + + //!< Call if getType() is not kPath to get the element as a round rect. + const SkRRect& asRRect() const { SkASSERT(kPath_Type != fType); return fRRect; } /** If getType() is not kEmpty this indicates whether the clip shape should be anti-aliased when it is rasterized. */ @@ -102,7 +110,7 @@ class SK_API SkClipStack { void invertShapeFillType(); //!< Sets the set operation represented by the element. - void setOp(SkRegion::Op op) { fOp = op; } + void setOp(SkCanvas::ClipOp op) { fOp = op; } /** The GenID can be used by clip stack clients to cache representations of the clip. The ID corresponds to the set of clip elements up to and including this element within the @@ -118,10 +126,11 @@ class SK_API SkClipStack { const SkRect& getBounds() const { static const SkRect kEmpty = { 0, 0, 0, 0 }; switch (fType) { - case kRect_Type: - return fRect; + case kRect_Type: // fallthrough + case kRRect_Type: + return fRRect.getBounds(); case kPath_Type: - return fPath.getBounds(); + return fPath.get()->getBounds(); case kEmpty_Type: return kEmpty; default: @@ -137,9 +146,28 @@ class SK_API SkClipStack { bool contains(const SkRect& rect) const { switch (fType) { case kRect_Type: - return fRect.contains(rect); + return this->getRect().contains(rect); + case kRRect_Type: + return fRRect.contains(rect); case kPath_Type: - return fPath.conservativelyContainsRect(rect); + return fPath.get()->conservativelyContainsRect(rect); + case kEmpty_Type: + return false; + default: + SkDEBUGFAIL("Unexpected type."); + return false; + } + } + + bool contains(const SkRRect& rrect) const { + switch (fType) { + case kRect_Type: + return this->getRect().contains(rrect.getBounds()); + case kRRect_Type: + // We don't currently have a generalized rrect-rrect containment. + return fRRect.contains(rrect.getBounds()) || rrect == fRRect; + case kPath_Type: + return fPath.get()->conservativelyContainsRect(rrect.getBounds()); case kEmpty_Type: return false; default: @@ -152,18 +180,29 @@ class SK_API SkClipStack { * Is the clip shape inverse filled. */ bool isInverseFilled() const { - return kPath_Type == fType && fPath.isInverseFillType(); + return kPath_Type == fType && fPath.get()->isInverseFillType(); } - // MM - SkRegion::Op fOp; - + /** + * Replay this clip into the visitor. + */ + void replay(SkCanvasClipVisitor*) const; + +#ifdef SK_DEBUG + /** + * Dumps the element to SkDebugf. This is intended for Skia development debugging + * Don't rely on the existence of this function or the formatting of its output. + */ + void dump() const; +#endif + private: friend class SkClipStack; - SkPath fPath; - SkRect fRect; + SkTLazy fPath; + SkRRect fRRect; int fSaveCount; // save count of stack when this element was added. + SkCanvas::ClipOp fOp; Type fType; bool fDoAA; @@ -187,19 +226,23 @@ class SK_API SkClipStack { int fGenID; Element(int saveCount) { - this->initCommon(saveCount, SkRegion::kReplace_Op, false); + this->initCommon(saveCount, SkCanvas::kReplace_Op, false); this->setEmpty(); } - Element(int saveCount, const SkRect& rect, SkRegion::Op op, bool doAA) { + Element(int saveCount, const SkRRect& rrect, SkCanvas::ClipOp op, bool doAA) { + this->initRRect(saveCount, rrect, op, doAA); + } + + Element(int saveCount, const SkRect& rect, SkCanvas::ClipOp op, bool doAA) { this->initRect(saveCount, rect, op, doAA); } - Element(int saveCount, const SkPath& path, SkRegion::Op op, bool doAA) { + Element(int saveCount, const SkPath& path, SkCanvas::ClipOp op, bool doAA) { this->initPath(saveCount, path, op, doAA); } - void initCommon(int saveCount, SkRegion::Op op, bool doAA) { + void initCommon(int saveCount, SkCanvas::ClipOp op, bool doAA) { fSaveCount = saveCount; fOp = op; fDoAA = doAA; @@ -211,31 +254,30 @@ class SK_API SkClipStack { fGenID = kInvalidGenID; } - void initRect(int saveCount, const SkRect& rect, SkRegion::Op op, bool doAA) { - fRect = rect; + void initRect(int saveCount, const SkRect& rect, SkCanvas::ClipOp op, bool doAA) { + fRRect.setRect(rect); fType = kRect_Type; this->initCommon(saveCount, op, doAA); } - void initPath(int saveCount, const SkPath& path, SkRegion::Op op, bool doAA) { - fPath = path; - fType = kPath_Type; + void initRRect(int saveCount, const SkRRect& rrect, SkCanvas::ClipOp op, bool doAA) { + SkRRect::Type type = rrect.getType(); + fRRect = rrect; + if (SkRRect::kRect_Type == type || SkRRect::kEmpty_Type == type) { + fType = kRect_Type; + } else { + fType = kRRect_Type; + } this->initCommon(saveCount, op, doAA); } - void setEmpty() { - fType = kEmpty_Type; - fFiniteBound.setEmpty(); - fFiniteBoundType = kNormal_BoundsType; - fIsIntersectionOfRects = false; - fRect.setEmpty(); - fPath.reset(); - fGenID = kEmptyGenID; - } + void initPath(int saveCount, const SkPath& path, SkCanvas::ClipOp op, bool doAA); + + void setEmpty(); // All Element methods below are only used within SkClipStack.cpp inline void checkEmpty() const; - inline bool canBeIntersectedInPlace(int saveCount, SkRegion::Op op) const; + inline bool canBeIntersectedInPlace(int saveCount, SkCanvas::ClipOp op) const; /* This method checks to see if two rect clips can be safely merged into one. The issue here is that to be strictly correct all the edges of the resulting rect must have the same anti-aliasing. */ @@ -260,8 +302,6 @@ class SK_API SkClipStack { SkClipStack(); SkClipStack(const SkClipStack& b); - explicit SkClipStack(const SkRect& r); - explicit SkClipStack(const SkIRect& r); ~SkClipStack(); SkClipStack& operator=(const SkClipStack& b); @@ -288,26 +328,32 @@ class SK_API SkClipStack { bool* isIntersectionOfRects = NULL) const; /** - * Takes an input rect in device space and conservatively clips it to the - * clip-stack. If false is returned then the rect does not intersect the - * clip and is unmodified. + * Returns true if the input (r)rect in device space is entirely contained + * by the clip. A return value of false does not guarantee that the (r)rect + * is not contained by the clip. */ - bool intersectRectWithClip(SkRect* devRect) const; + bool quickContains(const SkRect& devRect) const { + return this->isWideOpen() || this->internalQuickContains(devRect); + } + + bool quickContains(const SkRRect& devRRect) const { + return this->isWideOpen() || this->internalQuickContains(devRRect); + } /** - * Returns true if the input rect in device space is entirely contained - * by the clip. A return value of false does not guarantee that the rect - * is not contained by the clip. + * Flattens the clip stack into a single SkPath. Returns true if any of + * the clip stack components requires anti-aliasing. */ - bool quickContains(const SkRect& devRect) const; + bool asPath(SkPath* path) const; - void clipDevRect(const SkIRect& ir, SkRegion::Op op) { + void clipDevRect(const SkIRect& ir, SkCanvas::ClipOp op) { SkRect r; r.set(ir); - this->clipDevRect(r, op, false); + this->clipRect(r, SkMatrix::I(), op, false); } - void clipDevRect(const SkRect&, SkRegion::Op, bool doAA); - void clipDevPath(const SkPath&, SkRegion::Op, bool doAA); + void clipRect(const SkRect&, const SkMatrix& matrix, SkCanvas::ClipOp, bool doAA); + void clipRRect(const SkRRect&, const SkMatrix& matrix, SkCanvas::ClipOp, bool doAA); + void clipPath(const SkPath&, const SkMatrix& matrix, SkCanvas::ClipOp, bool doAA); // An optimized version of clipDevRect(emptyRect, kIntersect, ...) void clipEmpty(); @@ -315,7 +361,22 @@ class SK_API SkClipStack { * isWideOpen returns true if the clip state corresponds to the infinite * plane (i.e., draws are not limited at all) */ - bool isWideOpen() const; + bool isWideOpen() const { return this->getTopmostGenID() == kWideOpenGenID; } + + /** + * This method quickly and conservatively determines whether the entire stack is equivalent to + * intersection with a rrect given a bounds, where the rrect must not contain the entire bounds. + * + * @param bounds A bounds on what will be drawn through the clip. The clip only need be + * equivalent to a intersection with a rrect for draws within the bounds. The + * returned rrect must intersect the bounds but need not be contained by the + * bounds. + * @param rrect If return is true rrect will contain the rrect equivalent to the stack. + * @param aa If return is true aa will indicate whether the equivalent rrect clip is + * antialiased. + * @return true if the stack is equivalent to a single rrect intersect clip, false otherwise. + */ + bool isRRect(const SkRect& bounds, SkRRect* rrect, bool* aa) const; /** * The generation ID has three reserved values to indicate special @@ -329,6 +390,14 @@ class SK_API SkClipStack { int32_t getTopmostGenID() const; +#ifdef SK_DEBUG + /** + * Dumps the contents of the clip stack to SkDebugf. This is intended for Skia development + * debugging. Don't rely on the existence of this function or the formatting of its output. + */ + void dump() const; +#endif + public: class Iter { public: @@ -355,7 +424,7 @@ class SK_API SkClipStack { * Moves the iterator to the topmost element with the specified RegionOp and returns that * element. If no clip element with that op is found, the first element is returned. */ - const Element* skipToTopmost(SkRegion::Op op); + const Element* skipToTopmost(SkCanvas::ClipOp op); /** * Restarts the iterator on a clip stack. @@ -429,6 +498,14 @@ class SK_API SkClipStack { // invalid ID. static int32_t gGenID; + bool internalQuickContains(const SkRect& devRect) const; + bool internalQuickContains(const SkRRect& devRRect) const; + + /** + * Helper for clipDevPath, etc. + */ + void pushElement(const Element& element); + /** * Restore the stack back to the specified save count. */ diff --git a/libskia/include/core/SkColor.h b/libskia/include/core/SkColor.h index 7faeca7f..8f2776da 100644 --- a/libskia/include/core/SkColor.h +++ b/libskia/include/core/SkColor.h @@ -1,4 +1,3 @@ - /* * Copyright 2006 The Android Open Source Project * @@ -6,11 +5,12 @@ * found in the LICENSE file. */ - #ifndef SkColor_DEFINED #define SkColor_DEFINED #include "SkScalar.h" +#include "SkPoint3.h" +#include "SkTypes.h" /** \file SkColor.h @@ -111,8 +111,7 @@ SK_API void SkRGBToHSV(U8CPU red, U8CPU green, U8CPU blue, SkScalar hsv[3]); @param color the argb color to convert. Note: the alpha component is ignored. @param hsv 3 element array which holds the resulting HSV components. */ -static inline void SkColorToHSV(SkColor color, SkScalar hsv[3]) -{ +static inline void SkColorToHSV(SkColor color, SkScalar hsv[3]) { SkRGBToHSV(SkColorGetR(color), SkColorGetG(color), SkColorGetB(color), hsv); } @@ -135,8 +134,7 @@ SK_API SkColor SkHSVToColor(U8CPU alpha, const SkScalar hsv[3]); @param hsv 3 element array which holds the input HSV components. @return the resulting argb color */ -static inline SkColor SkHSVToColor(const SkScalar hsv[3]) -{ +static inline SkColor SkHSVToColor(const SkScalar hsv[3]) { return SkHSVToColor(0xFF, hsv); } @@ -161,9 +159,40 @@ SK_API SkPMColor SkPreMultiplyColor(SkColor c); */ typedef SkPMColor (*SkXfermodeProc)(SkPMColor src, SkPMColor dst); -/** Define a function pointer type for combining a premultiplied src color - and a 16bit device color. -*/ -typedef uint16_t (*SkXfermodeProc16)(SkPMColor src, uint16_t dst); +/////////////////////////////////////////////////////////////////////////////////////////////////// + +struct SkPM4f; + +/* + * The float values are 0...1 unpremultiplied + */ +struct SkColor4f { + float fR; + float fG; + float fB; + float fA; + + bool operator==(const SkColor4f& other) const { + return fA == other.fA && fR == other.fR && fG == other.fG && fB == other.fB; + } + bool operator!=(const SkColor4f& other) const { + return !(*this == other); + } + + const float* vec() const { return &fR; } + float* vec() { return &fR; } + + static SkColor4f Pin(float r, float g, float b, float a); + static SkColor4f FromColor(SkColor); + static SkColor4f FromColor3f(SkColor3f, float a); + + SkColor toSkColor() const; + + SkColor4f pin() const { + return Pin(fR, fG, fB, fA); + } + + SkPM4f premul() const; +}; #endif diff --git a/libskia/include/core/SkColorFilter.h b/libskia/include/core/SkColorFilter.h index 106e5bb8..fd3ccbc7 100644 --- a/libskia/include/core/SkColorFilter.h +++ b/libskia/include/core/SkColorFilter.h @@ -1,4 +1,3 @@ - /* * Copyright 2006 The Android Open Source Project * @@ -6,17 +5,20 @@ * found in the LICENSE file. */ - #ifndef SkColorFilter_DEFINED #define SkColorFilter_DEFINED +#include "SkBlendMode.h" #include "SkColor.h" #include "SkFlattenable.h" -#include "SkXfermode.h" +#include "SkRefCnt.h" -class SkBitmap; -class GrEffectRef; class GrContext; +class GrFragmentProcessor; +class SkBitmap; +class SkColorSpace; +class SkFallbackAlloc; +class SkRasterPipeline; /** * ColorFilters are optional objects in the drawing pipeline. When present in @@ -28,14 +30,12 @@ class GrContext; */ class SK_API SkColorFilter : public SkFlattenable { public: - SK_DECLARE_INST_COUNT(SkColorFilter) - /** * If the filter can be represented by a source color plus Mode, this * returns true, and sets (if not NULL) the color and mode appropriately. * If not, this returns false and ignores the parameters. */ - virtual bool asColorMode(SkColor* color, SkXfermode::Mode* mode) const; + virtual bool asColorMode(SkColor* color, SkBlendMode* bmode) const; /** * If the filter can be represented by a 5x4 matrix, this @@ -69,34 +69,32 @@ class SK_API SkColorFilter : public SkFlattenable { @param count the number of entries in the src[] and result[] arrays @param result written by the filter */ - virtual void filterSpan(const SkPMColor src[], int count, - SkPMColor result[]) const = 0; - /** Called with a scanline of colors, as if there was a shader installed. - The implementation writes out its filtered version into result[]. - Note: shader and result may be the same buffer. - @param src array of colors, possibly generated by a shader - @param count the number of entries in the src[] and result[] arrays - @param result written by the filter - */ - virtual void filterSpan16(const uint16_t shader[], int count, - uint16_t result[]) const; + virtual void filterSpan(const SkPMColor src[], int count, SkPMColor result[]) const = 0; + + virtual void filterSpan4f(const SkPM4f src[], int count, SkPM4f result[]) const; + + bool appendStages(SkRasterPipeline*, SkColorSpace*, SkFallbackAlloc*, + bool shaderIsOpaque) const; enum Flags { - /** If set the filter methods will not change the alpha channel of the - colors. + /** If set the filter methods will not change the alpha channel of the colors. */ - kAlphaUnchanged_Flag = 0x01, - /** If set, this subclass implements filterSpan16(). If this flag is - set, then kAlphaUnchanged_Flag must also be set. - */ - kHasFilter16_Flag = 0x02 + kAlphaUnchanged_Flag = 1 << 0, }; - /** Returns the flags for this filter. Override in subclasses to return - custom flags. + /** Returns the flags for this filter. Override in subclasses to return custom flags. */ virtual uint32_t getFlags() const { return 0; } + /** + * If this subclass can optimally createa composition with the inner filter, return it as + * a new filter (which the caller must unref() when it is done). If no such optimization + * is known, return NULL. + * + * e.g. result(color) == this_filter(inner(color)) + */ + virtual sk_sp makeComposed(sk_sp) const { return nullptr; } + /** * Apply this colorfilter to the specified SkColor. This routine handles * converting to SkPMColor, calling the filter, and then converting back @@ -105,39 +103,77 @@ class SK_API SkColorFilter : public SkFlattenable { */ SkColor filterColor(SkColor) const; + /** + * Filters a single color. + */ + SkColor4f filterColor4f(const SkColor4f&) const; + /** Create a colorfilter that uses the specified color and mode. If the Mode is DST, this function will return NULL (since that mode will have no effect on the result). @param c The source color used with the specified mode - @param mode The xfermode mode that is applied to each color in + @param mode The blend that is applied to each color in the colorfilter's filterSpan[16,32] methods @return colorfilter object that applies the src color and mode, or NULL if the mode will have no effect. */ - static SkColorFilter* CreateModeFilter(SkColor c, SkXfermode::Mode mode); + static sk_sp MakeModeFilter(SkColor c, SkBlendMode mode); - /** Create a colorfilter that multiplies the RGB channels by one color, and - then adds a second color, pinning the result for each component to - [0..255]. The alpha components of the mul and add arguments - are ignored. - */ - static SkColorFilter* CreateLightingFilter(SkColor mul, SkColor add); + /** Construct a colorfilter whose effect is to first apply the inner filter and then apply + * the outer filter to the result of the inner's. + * The reference counts for outer and inner are incremented. + * + * Due to internal limits, it is possible that this will return NULL, so the caller must + * always check. + */ + static sk_sp MakeComposeFilter(sk_sp outer, + sk_sp inner); + + /** Construct a color filter that transforms a color by a 4x5 matrix. The matrix is in row- + * major order and the translation column is specified in unnormalized, 0...255, space. + */ + static sk_sp MakeMatrixFilterRowMajor255(const SkScalar array[20]); - /** A subclass may implement this factory function to work with the GPU backend. If the return - is non-NULL then the caller owns a ref on the returned object. +#if SK_SUPPORT_GPU + /** + * A subclass may implement this factory function to work with the GPU backend. It returns + * a GrFragmentProcessor that implemets the color filter in GPU shader code. + * + * The fragment processor receives a premultiplied input color and produces a premultiplied + * output color. + * + * A null return indicates that the color filter isn't implemented for the GPU backend. */ - virtual GrEffectRef* asNewEffect(GrContext*) const; + virtual sk_sp asFragmentProcessor(GrContext*, + SkColorSpace* dstColorSpace) const; +#endif + + bool affectsTransparentBlack() const { + return this->filterColor(0) != 0; + } - SkDEVCODE(virtual void toString(SkString* str) const = 0;) + SK_TO_STRING_PUREVIRT() SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP() SK_DEFINE_FLATTENABLE_TYPE(SkColorFilter) protected: SkColorFilter() {} - SkColorFilter(SkFlattenableReadBuffer& rb) : INHERITED(rb) {} + + virtual bool onAppendStages(SkRasterPipeline*, SkColorSpace*, SkFallbackAlloc*, + bool shaderIsOpaque) const; private: + /* + * Returns 1 if this is a single filter (not a composition of other filters), otherwise it + * reutrns the number of leaf-node filters in a composition. This should be the same value + * as the number of GrFragmentProcessors returned by asFragmentProcessors's array parameter. + * + * e.g. compose(filter, compose(compose(filter, filter), filter)) --> 4 + */ + virtual int privateComposedFilterCount() const { return 1; } + friend class SkComposeColorFilter; + typedef SkFlattenable INHERITED; }; diff --git a/libskia/include/core/SkColorPriv.h b/libskia/include/core/SkColorPriv.h index 7a74c4a0..694d3247 100644 --- a/libskia/include/core/SkColorPriv.h +++ b/libskia/include/core/SkColorPriv.h @@ -1,4 +1,3 @@ - /* * Copyright 2006 The Android Open Source Project * @@ -6,7 +5,6 @@ * found in the LICENSE file. */ - #ifndef SkColorPriv_DEFINED #define SkColorPriv_DEFINED @@ -18,6 +16,139 @@ #include "SkColor.h" #include "SkMath.h" +////////////////////////////////////////////////////////////////////////////// + +#define SkASSERT_IS_BYTE(x) SkASSERT(0 == ((x) & ~0xFF)) + +/* + * Skia's 32bit backend only supports 1 sizzle order at a time (compile-time). + * This is specified by 4 defines SK_A32_SHIFT, SK_R32_SHIFT, ... for G and B. + * + * For easier compatibility with Skia's GPU backend, we further restrict these + * to either (in memory-byte-order) RGBA or BGRA. Note that this "order" does + * not directly correspond to the same shift-order, since we have to take endianess + * into account. + * + * Here we enforce this constraint. + */ + +#ifdef SK_CPU_BENDIAN + #define SK_RGBA_R32_SHIFT 24 + #define SK_RGBA_G32_SHIFT 16 + #define SK_RGBA_B32_SHIFT 8 + #define SK_RGBA_A32_SHIFT 0 + + #define SK_BGRA_B32_SHIFT 24 + #define SK_BGRA_G32_SHIFT 16 + #define SK_BGRA_R32_SHIFT 8 + #define SK_BGRA_A32_SHIFT 0 +#else + #define SK_RGBA_R32_SHIFT 0 + #define SK_RGBA_G32_SHIFT 8 + #define SK_RGBA_B32_SHIFT 16 + #define SK_RGBA_A32_SHIFT 24 + + #define SK_BGRA_B32_SHIFT 0 + #define SK_BGRA_G32_SHIFT 8 + #define SK_BGRA_R32_SHIFT 16 + #define SK_BGRA_A32_SHIFT 24 +#endif + +#if defined(SK_PMCOLOR_IS_RGBA) && defined(SK_PMCOLOR_IS_BGRA) + #error "can't define PMCOLOR to be RGBA and BGRA" +#endif + +#define LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_RGBA \ + (SK_A32_SHIFT == SK_RGBA_A32_SHIFT && \ + SK_R32_SHIFT == SK_RGBA_R32_SHIFT && \ + SK_G32_SHIFT == SK_RGBA_G32_SHIFT && \ + SK_B32_SHIFT == SK_RGBA_B32_SHIFT) + +#define LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_BGRA \ + (SK_A32_SHIFT == SK_BGRA_A32_SHIFT && \ + SK_R32_SHIFT == SK_BGRA_R32_SHIFT && \ + SK_G32_SHIFT == SK_BGRA_G32_SHIFT && \ + SK_B32_SHIFT == SK_BGRA_B32_SHIFT) + + +#define SK_A_INDEX (SK_A32_SHIFT/8) +#define SK_R_INDEX (SK_R32_SHIFT/8) +#define SK_G_INDEX (SK_G32_SHIFT/8) +#define SK_B_INDEX (SK_B32_SHIFT/8) + +#if defined(SK_PMCOLOR_IS_RGBA) && !LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_RGBA + #error "SK_PMCOLOR_IS_RGBA does not match SK_*32_SHIFT values" +#endif + +#if defined(SK_PMCOLOR_IS_BGRA) && !LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_BGRA + #error "SK_PMCOLOR_IS_BGRA does not match SK_*32_SHIFT values" +#endif + +#if !defined(SK_PMCOLOR_IS_RGBA) && !defined(SK_PMCOLOR_IS_BGRA) + // deduce which to define from the _SHIFT defines + + #if LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_RGBA + #define SK_PMCOLOR_IS_RGBA + #elif LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_BGRA + #define SK_PMCOLOR_IS_BGRA + #else + #error "need 32bit packing to be either RGBA or BGRA" + #endif +#endif + +// hide these now that we're done +#undef LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_RGBA +#undef LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_BGRA + +////////////////////////////////////////////////////////////////////////////// + +// Reverse the bytes coorsponding to RED and BLUE in a packed pixels. Note the +// pair of them are in the same 2 slots in both RGBA and BGRA, thus there is +// no need to pass in the colortype to this function. +static inline uint32_t SkSwizzle_RB(uint32_t c) { + static const uint32_t kRBMask = (0xFF << SK_R32_SHIFT) | (0xFF << SK_B32_SHIFT); + + unsigned c0 = (c >> SK_R32_SHIFT) & 0xFF; + unsigned c1 = (c >> SK_B32_SHIFT) & 0xFF; + return (c & ~kRBMask) | (c0 << SK_B32_SHIFT) | (c1 << SK_R32_SHIFT); +} + +static inline uint32_t SkPackARGB_as_RGBA(U8CPU a, U8CPU r, U8CPU g, U8CPU b) { + SkASSERT_IS_BYTE(a); + SkASSERT_IS_BYTE(r); + SkASSERT_IS_BYTE(g); + SkASSERT_IS_BYTE(b); + return (a << SK_RGBA_A32_SHIFT) | (r << SK_RGBA_R32_SHIFT) | + (g << SK_RGBA_G32_SHIFT) | (b << SK_RGBA_B32_SHIFT); +} + +static inline uint32_t SkPackARGB_as_BGRA(U8CPU a, U8CPU r, U8CPU g, U8CPU b) { + SkASSERT_IS_BYTE(a); + SkASSERT_IS_BYTE(r); + SkASSERT_IS_BYTE(g); + SkASSERT_IS_BYTE(b); + return (a << SK_BGRA_A32_SHIFT) | (r << SK_BGRA_R32_SHIFT) | + (g << SK_BGRA_G32_SHIFT) | (b << SK_BGRA_B32_SHIFT); +} + +static inline SkPMColor SkSwizzle_RGBA_to_PMColor(uint32_t c) { +#ifdef SK_PMCOLOR_IS_RGBA + return c; +#else + return SkSwizzle_RB(c); +#endif +} + +static inline SkPMColor SkSwizzle_BGRA_to_PMColor(uint32_t c) { +#ifdef SK_PMCOLOR_IS_BGRA + return c; +#else + return SkSwizzle_RB(c); +#endif +} + +////////////////////////////////////////////////////////////////////////////// + ///@{ /** See ITU-R Recommendation BT.709 at http://www.itu.int/rec/R-REC-BT.709/ .*/ #define SK_ITU_BT709_LUM_COEFF_R (0.2126f) @@ -55,10 +186,31 @@ static inline unsigned SkAlpha255To256(U8CPU alpha) { return alpha + 1; } +/** + * Turn a 0..255 value into a 0..256 value, rounding up if the value is >= 0x80. + * This is slightly more accurate than SkAlpha255To256. + */ +static inline unsigned Sk255To256(U8CPU value) { + SkASSERT(SkToU8(value) == value); + return value + (value >> 7); +} + /** Multiplify value by 0..256, and shift the result down 8 (i.e. return (value * alpha256) >> 8) */ -#define SkAlphaMul(value, alpha256) (SkMulS16(value, alpha256) >> 8) +#define SkAlphaMul(value, alpha256) (((value) * (alpha256)) >> 8) + +/** Calculates 256 - (value * alpha256) / 255 in range [0,256], + * for [0,255] value and [0,256] alpha256. + */ +static inline U16CPU SkAlphaMulInv256(U16CPU value, U16CPU alpha256) { +#ifdef SK_SUPPORT_LEGACY_BROKEN_LERP + return SkAlpha255To256(255 - SkAlphaMul(value, alpha256)); +#else + unsigned prod = 0xFFFF - value * alpha256; + return (prod + (prod >> 8)) >> 8; +#endif +} // The caller may want negative values, so keep all params signed (int) // so we don't accidentally slip into unsigned math and lose the sign @@ -78,11 +230,15 @@ static inline int SkAlphaBlend255(S16CPU src, S16CPU dst, U8CPU alpha) { SkASSERT((int16_t)dst == dst); SkASSERT((uint8_t)alpha == alpha); - int prod = SkMulS16(src - dst, alpha) + 128; + int prod = (src - dst) * alpha + 128; prod = (prod + (prod >> 8)) >> 8; return dst + prod; } +static inline U8CPU SkUnitScalarClampToByte(SkScalar x) { + return static_cast(SkScalarPin(x, 0, 1) * 255 + 0.5); +} + #define SK_R16_BITS 5 #define SK_G16_BITS 6 #define SK_B16_BITS 5 @@ -146,6 +302,16 @@ static inline U16CPU SkAlphaMulRGB16(U16CPU c, unsigned scale) { // this helper explicitly returns a clean 16bit value (but slower) #define SkAlphaMulRGB16_ToU16(c, s) (uint16_t)SkAlphaMulRGB16(c, s) +/** Blend pre-expanded RGB32 with 16bit color value by the 0..32 scale parameter. + The computation yields only 16bits of valid data, but we claim to return + 32bits, so that the compiler won't generate extra instructions to "clean" + the top 16bits. +*/ +static inline U16CPU SkBlend32_RGB16(uint32_t src_expand, uint16_t dst, unsigned scale) { + uint32_t dst_expand = SkExpand_rgb_16(dst) * scale; + return SkCompact_rgb_16((src_expand + dst_expand) >> 5); +} + /** Blend src and dst 16bit colors by the 0..256 scale parameter. The computation yields only 16bits of valid data, but we claim to return 32bits, so that the compiler won't generate extra instructions to @@ -171,7 +337,8 @@ static inline void SkBlendRGB16(const uint16_t src[], uint16_t dst[], do { uint32_t src32 = SkExpand_rgb_16(*src++); uint32_t dst32 = SkExpand_rgb_16(*dst); - *dst++ = SkCompact_rgb_16(dst32 + ((src32 - dst32) * srcScale >> 5)); + *dst++ = static_cast( + SkCompact_rgb_16(dst32 + ((src32 - dst32) * srcScale >> 5))); } while (--count > 0); } @@ -210,21 +377,31 @@ static inline void SkBlendRGB16(const uint16_t src[], uint16_t dst[], #define SkB32Assert(b) SkASSERT((unsigned)(b) <= SK_B32_MASK) #ifdef SK_DEBUG - static inline void SkPMColorAssert(SkPMColor c) { - unsigned a = SkGetPackedA32(c); - unsigned r = SkGetPackedR32(c); - unsigned g = SkGetPackedG32(c); - unsigned b = SkGetPackedB32(c); - - SkA32Assert(a); - SkASSERT(r <= a); - SkASSERT(g <= a); - SkASSERT(b <= a); - } + #define SkPMColorAssert(color_value) \ + do { \ + SkPMColor pm_color_value = (color_value); \ + uint32_t alpha_color_value = SkGetPackedA32(pm_color_value); \ + SkA32Assert(alpha_color_value); \ + SkASSERT(SkGetPackedR32(pm_color_value) <= alpha_color_value); \ + SkASSERT(SkGetPackedG32(pm_color_value) <= alpha_color_value); \ + SkASSERT(SkGetPackedB32(pm_color_value) <= alpha_color_value); \ + } while (false) #else #define SkPMColorAssert(c) #endif +static inline bool SkPMColorValid(SkPMColor c) { + auto a = SkGetPackedA32(c); + bool valid = a <= SK_A32_MASK + && SkGetPackedR32(c) <= a + && SkGetPackedG32(c) <= a + && SkGetPackedB32(c) <= a; + if (valid) { + SkPMColorAssert(c); // Make sure we're consistent when it counts. + } + return valid; +} + /** * Pack the components into a SkPMColor, checking (in the debug version) that * the components are 0..255, and are already premultiplied (i.e. alpha >= color) @@ -239,6 +416,16 @@ static inline SkPMColor SkPackARGB32(U8CPU a, U8CPU r, U8CPU g, U8CPU b) { (g << SK_G32_SHIFT) | (b << SK_B32_SHIFT); } +static inline uint32_t SkPackPMColor_as_RGBA(SkPMColor c) { + return SkPackARGB_as_RGBA(SkGetPackedA32(c), SkGetPackedR32(c), + SkGetPackedG32(c), SkGetPackedB32(c)); +} + +static inline uint32_t SkPackPMColor_as_BGRA(SkPMColor c) { + return SkPackARGB_as_BGRA(SkGetPackedA32(c), SkGetPackedR32(c), + SkGetPackedG32(c), SkGetPackedB32(c)); +} + /** * Abstract 4-byte interpolation, implemented on top of SkPMColor * utility functions. Third parameter controls blending of the first two: @@ -379,10 +566,10 @@ SkPMColor SkPremultiplyARGBInline(U8CPU a, U8CPU r, U8CPU g, U8CPU b) { return SkPackARGB32(a, r, g, b); } -SK_API extern const uint32_t gMask_00FF00FF; - -static inline uint32_t SkAlphaMulQ(uint32_t c, unsigned scale) { - uint32_t mask = gMask_00FF00FF; +// When Android is compiled optimizing for size, SkAlphaMulQ doesn't get +// inlined; forcing inlining significantly improves performance. +static SK_ALWAYS_INLINE uint32_t SkAlphaMulQ(uint32_t c, unsigned scale) { + uint32_t mask = 0xFF00FF; uint32_t rb = ((c & mask) * scale) >> 8; uint32_t ag = ((c >> 8) & mask) * scale; @@ -393,13 +580,38 @@ static inline SkPMColor SkPMSrcOver(SkPMColor src, SkPMColor dst) { return src + SkAlphaMulQ(dst, SkAlpha255To256(255 - SkGetPackedA32(src))); } +/** + * Interpolates between colors src and dst using [0,256] scale. + */ +static inline SkPMColor SkPMLerp(SkPMColor src, SkPMColor dst, unsigned scale) { +#ifdef SK_SUPPORT_LEGACY_BROKEN_LERP + return SkAlphaMulQ(src, scale) + SkAlphaMulQ(dst, 256 - scale); +#else + return SkFastFourByteInterp256(src, dst, scale); +#endif +} + static inline SkPMColor SkBlendARGB32(SkPMColor src, SkPMColor dst, U8CPU aa) { SkASSERT((unsigned)aa <= 255); unsigned src_scale = SkAlpha255To256(aa); +#ifdef SK_SUPPORT_LEGACY_BROKEN_LERP unsigned dst_scale = SkAlpha255To256(255 - SkAlphaMul(SkGetPackedA32(src), src_scale)); return SkAlphaMulQ(src, src_scale) + SkAlphaMulQ(dst, dst_scale); +#else + unsigned dst_scale = SkAlphaMulInv256(SkGetPackedA32(src), src_scale); + + const uint32_t mask = 0xFF00FF; + + uint32_t src_rb = (src & mask) * src_scale; + uint32_t src_ag = ((src >> 8) & mask) * src_scale; + + uint32_t dst_rb = (dst & mask) * dst_scale; + uint32_t dst_ag = ((dst >> 8) & mask) * dst_scale; + + return (((src_rb + dst_rb) >> 8) & mask) | ((src_ag + dst_ag) & ~mask); +#endif } //////////////////////////////////////////////////////////////////////////////////////////// @@ -642,9 +854,7 @@ static inline SkPMColor16 SkPackARGB4444(unsigned a, unsigned r, (g << SK_G4444_SHIFT) | (b << SK_B4444_SHIFT)); } -extern const uint16_t gMask_0F0F; - -static inline U16CPU SkAlphaMulQ4(U16CPU c, unsigned scale) { +static inline SkPMColor16 SkAlphaMulQ4(SkPMColor16 c, int scale) { SkASSERT(scale <= 16); const unsigned mask = 0xF0F; //gMask_0F0F; @@ -654,14 +864,14 @@ static inline U16CPU SkAlphaMulQ4(U16CPU c, unsigned scale) { unsigned ag = ((c >> 4) & mask) * scale; return (rb & mask) | (ag & ~mask); #else - c = (c & mask) | ((c & (mask << 4)) << 12); - c = c * scale >> 4; - return (c & mask) | ((c >> 12) & (mask << 4)); + unsigned expanded_c = (c & mask) | ((c & (mask << 4)) << 12); + unsigned scaled_c = (expanded_c * scale) >> 4; + return (scaled_c & mask) | ((scaled_c >> 12) & (mask << 4)); #endif } /** Expand the SkPMColor16 color into a 32bit value that can be scaled all at - once by a value up to 16. Used in conjunction with SkCompact_4444. + once by a value up to 16. */ static inline uint32_t SkExpand_4444(U16CPU c) { SkASSERT(c == (uint16_t)c); @@ -670,18 +880,6 @@ static inline uint32_t SkExpand_4444(U16CPU c) { return (c & mask) | ((c & ~mask) << 12); } -/** Compress an expanded value (from SkExpand_4444) back down to a SkPMColor16. - NOTE: this explicitly does not clean the top 16 bits (which may be garbage). - It does this for speed, since if it is being written directly to 16bits of - memory, the top 16bits will be ignored. Casting the result to uint16_t here - would add 2 more instructions, slow us down. It is up to the caller to - perform the cast if needed. -*/ -static inline U16CPU SkCompact_4444(uint32_t c) { - const unsigned mask = 0xF0F; //gMask_0F0F; - return (c & mask) | ((c >> 12) & ~mask); -} - static inline uint16_t SkSrcOver4444To16(SkPMColor16 s, uint16_t d) { unsigned sa = SkGetPackedA4444(s); unsigned sr = SkR4444ToR565(SkGetPackedR4444(s)); @@ -713,22 +911,6 @@ static inline uint16_t SkBlend4444To16(SkPMColor16 src, uint16_t dst, int scale1 return SkSrcOver4444To16(SkAlphaMulQ4(src, scale16), dst); } -static inline uint16_t SkBlend4444(SkPMColor16 src, SkPMColor16 dst, int scale16) { - SkASSERT((unsigned)scale16 <= 16); - - uint32_t src32 = SkExpand_4444(src) * scale16; - // the scaled srcAlpha is the bottom byte -#ifdef SK_DEBUG - { - unsigned srcA = SkGetPackedA4444(src) * scale16; - SkASSERT(srcA == (src32 & 0xFF)); - } -#endif - unsigned dstScale = SkAlpha255To256(255 - (src32 & 0xFF)) >> 4; - uint32_t dst32 = SkExpand_4444(dst) * dstScale; - return SkCompact_4444((src32 + dst32) >> 4); -} - static inline SkPMColor SkPixel4444ToPixel32(U16CPU c) { uint32_t d = (SkGetPackedA4444(c) << SK_A32_SHIFT) | (SkGetPackedR4444(c) << SK_R32_SHIFT) | diff --git a/libskia/include/core/SkColorShader.h b/libskia/include/core/SkColorShader.h deleted file mode 100644 index c3790682..00000000 --- a/libskia/include/core/SkColorShader.h +++ /dev/null @@ -1,69 +0,0 @@ - -/* - * Copyright 2007 The Android Open Source Project - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - - -#ifndef SkColorShader_DEFINED -#define SkColorShader_DEFINED - -#include "SkShader.h" - -/** \class SkColorShader - A Shader that represents a single color. In general, this effect can be - accomplished by just using the color field on the paint, but if an - actual shader object is needed, this provides that feature. -*/ -class SK_API SkColorShader : public SkShader { -public: - /** Create a ColorShader that will inherit its color from the Paint - at draw time. - */ - SkColorShader(); - - /** Create a ColorShader that ignores the color in the paint, and uses the - specified color. Note: like all shaders, at draw time the paint's alpha - will be respected, and is applied to the specified color. - */ - SkColorShader(SkColor c); - - virtual ~SkColorShader(); - - virtual uint32_t getFlags() SK_OVERRIDE; - virtual uint8_t getSpan16Alpha() const SK_OVERRIDE; - virtual bool isOpaque() const SK_OVERRIDE; - virtual bool setContext(const SkBitmap& device, const SkPaint& paint, - const SkMatrix& matrix) SK_OVERRIDE; - virtual void shadeSpan(int x, int y, SkPMColor span[], int count) SK_OVERRIDE; - virtual void shadeSpan16(int x, int y, uint16_t span[], int count) SK_OVERRIDE; - virtual void shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) SK_OVERRIDE; - - // we return false for this, use asAGradient - virtual BitmapType asABitmap(SkBitmap* outTexture, - SkMatrix* outMatrix, - TileMode xy[2]) const SK_OVERRIDE; - - virtual GradientType asAGradient(GradientInfo* info) const SK_OVERRIDE; - - SK_DEVELOPER_TO_STRING() - SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkColorShader) - -protected: - SkColorShader(SkFlattenableReadBuffer&); - virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE; - -private: - - SkColor fColor; // ignored if fInheritColor is true - SkPMColor fPMColor; // cached after setContext() - uint32_t fFlags; // cached after setContext() - uint16_t fColor16; // cached after setContext() - SkBool8 fInheritColor; - - typedef SkShader INHERITED; -}; - -#endif diff --git a/libskia/include/core/SkColorSpace.h b/libskia/include/core/SkColorSpace.h new file mode 100644 index 00000000..2139cf84 --- /dev/null +++ b/libskia/include/core/SkColorSpace.h @@ -0,0 +1,144 @@ +/* + * Copyright 2016 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkColorSpace_DEFINED +#define SkColorSpace_DEFINED + +#include "SkMatrix44.h" +#include "SkRefCnt.h" + +class SkData; + +/** + * Describes a color gamut with primaries and a white point. + */ +struct SK_API SkColorSpacePrimaries { + float fRX, fRY; + float fGX, fGY; + float fBX, fBY; + float fWX, fWY; + + /** + * Convert primaries and a white point to a toXYZD50 matrix, the preferred color gamut + * representation of SkColorSpace. + */ + bool toXYZD50(SkMatrix44* toXYZD50) const; +}; + +/** + * Contains the coefficients for a common transfer function equation, specified as + * a transformation from a curved space to linear. + * + * LinearVal = E*InputVal + F , for 0.0f <= InputVal < D + * LinearVal = (A*InputVal + B)^G + C, for D <= InputVal <= 1.0f + * + * Function is undefined if InputVal is not in [ 0.0f, 1.0f ]. + * Resulting LinearVals must be in [ 0.0f, 1.0f ]. + * Function must be positive and increasing. + */ +struct SK_API SkColorSpaceTransferFn { + float fG; + float fA; + float fB; + float fC; + float fD; + float fE; + float fF; +}; + +class SK_API SkColorSpace : public SkRefCnt { +public: + + /** + * Common, named profiles that we can recognize. + */ + enum Named : uint8_t { + /** + * By far the most common color space. + * This is the default space for images, unmarked content, and monitors. + */ + kSRGB_Named, + + /** + * Very common wide gamut color space. + * Often used by images and monitors. + */ + kAdobeRGB_Named, + + /** + * Colorspace with the sRGB primaries, but a linear (1.0) gamma. Commonly used for + * half-float surfaces, and high precision individual colors (gradient stops, etc...) + */ + kSRGBLinear_Named, + }; + + enum RenderTargetGamma : uint8_t { + kLinear_RenderTargetGamma, + + /** + * Transfer function is the canonical sRGB curve, which has a short linear segment + * followed by a 2.4f exponential. + */ + kSRGB_RenderTargetGamma, + }; + + /** + * Create an SkColorSpace from a transfer function and a color gamut. + * + * Transfer function can be specified as a render target, as the coefficients to an equation, + * or as three exponents (R, G, B). + * Gamut is specified using the matrix transformation to XYZ D50. + */ + static sk_sp MakeRGB(RenderTargetGamma gamma, const SkMatrix44& toXYZD50); + static sk_sp MakeRGB(const SkColorSpaceTransferFn& coeffs, + const SkMatrix44& toXYZD50); + + /** + * Create a common, named SkColorSpace. + */ + static sk_sp MakeNamed(Named); + + /** + * Create an SkColorSpace from an ICC profile. + */ + static sk_sp MakeICC(const void*, size_t); + + /** + * Returns true if the color space gamma is near enough to be approximated as sRGB. + */ + bool gammaCloseToSRGB() const; + + /** + * Returns true if the color space gamma is linear. + */ + bool gammaIsLinear() const; + + /** + * Returns nullptr on failure. Fails when we fallback to serializing ICC data and + * the data is too large to serialize. + */ + sk_sp serialize() const; + + /** + * If |memory| is nullptr, returns the size required to serialize. + * Otherwise, serializes into |memory| and returns the size. + */ + size_t writeToMemory(void* memory) const; + + static sk_sp Deserialize(const void* data, size_t length); + + /** + * If both are null, we return true. If one is null and the other is not, we return false. + * If both are non-null, we do a deeper compare. + */ + static bool Equals(const SkColorSpace* src, const SkColorSpace* dst); + +protected: + SkColorSpace() {} +}; + +#endif diff --git a/libskia/include/core/SkColorSpaceXform.h b/libskia/include/core/SkColorSpaceXform.h new file mode 100644 index 00000000..b750c099 --- /dev/null +++ b/libskia/include/core/SkColorSpaceXform.h @@ -0,0 +1,61 @@ +/* + * Copyright 2016 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkColorSpaceXform_DEFINED +#define SkColorSpaceXform_DEFINED + +#include "SkImageInfo.h" + +class SkColorSpace; + +class SK_API SkColorSpaceXform : SkNoncopyable { +public: + + /** + * Create an object to handle color space conversions. + * + * @param srcSpace The encoded color space. + * @param dstSpace The destination color space. + * + */ + static std::unique_ptr New(SkColorSpace* srcSpace, SkColorSpace* dstSpace); + + enum ColorFormat { + kRGBA_8888_ColorFormat, + kBGRA_8888_ColorFormat, + kRGBA_F16_ColorFormat, + kRGBA_F32_ColorFormat, + }; + + /** + * Apply the color conversion to a |src| buffer, storing the output in the |dst| buffer. + * + * F16 and F32 are only supported as dst color formats, and only when the dst color space + * is linear. This function will return false in unsupported cases. + * + * @param dst Stored in the format described by |dstColorFormat| + * @param src Stored in the format described by |srcColorFormat| + * @param len Number of pixels in the buffers + * @param dstColorFormat Describes color format of |dst| + * @param srcColorFormat Describes color format of |src| + * Must be kRGBA_8888 or kBGRA_8888 + * @param alphaType Describes alpha properties of the |dst| (and |src|) + * kUnpremul preserves input alpha values + * kPremul performs a premultiplication and also preserves alpha values + * kOpaque optimization hint, |dst| alphas set to 1 + * + */ + bool apply(ColorFormat dstFormat, void* dst, ColorFormat srcFormat, const void* src, int count, + SkAlphaType alphaType) const; + + virtual ~SkColorSpaceXform() {} + +protected: + SkColorSpaceXform() {} +}; + +#endif diff --git a/libskia/include/core/SkColorTable.h b/libskia/include/core/SkColorTable.h index 52300fc4..07dfd675 100644 --- a/libskia/include/core/SkColorTable.h +++ b/libskia/include/core/SkColorTable.h @@ -10,6 +10,7 @@ #ifndef SkColorTable_DEFINED #define SkColorTable_DEFINED +#include "../private/SkOnce.h" #include "SkColor.h" #include "SkFlattenable.h" #include "SkImageInfo.h" @@ -18,75 +19,66 @@ SkColorTable holds an array SkPMColors (premultiplied 32-bit colors) used by 8-bit bitmaps, where the bitmap bytes are interpreted as indices into the colortable. + + SkColorTable is thread-safe. */ -class SkColorTable : public SkRefCnt { +class SK_API SkColorTable : public SkRefCnt { public: - SK_DECLARE_INST_COUNT(SkColorTable) - - /** Makes a deep copy of colors. + /** Copy up to 256 colors into a new SkColorTable. */ - SkColorTable(const SkColorTable& src); - SkColorTable(const SkPMColor colors[], int count, - SkAlphaType alphaType = kPremul_SkAlphaType); + SkColorTable(const SkPMColor colors[], int count); virtual ~SkColorTable(); - SkAlphaType alphaType() const { return (SkAlphaType)fAlphaType; } - - bool isOpaque() const { - return SkAlphaTypeIsOpaque(this->alphaType()); - } - /** Returns the number of colors in the table. - */ + */ int count() const { return fCount; } /** Returns the specified color from the table. In the debug build, this asserts that - the index is in range (0 <= index < count). - */ + * the index is in range (0 <= index < count). + */ SkPMColor operator[](int index) const { - SkASSERT(fColors != NULL && (unsigned)index < fCount); + SkASSERT(fColors != NULL && (unsigned)index < (unsigned)fCount); return fColors[index]; } - /** - * Return the array of colors for reading. This must be balanced by a call - * to unlockColors(). + /** Return the array of colors for reading. */ - const SkPMColor* lockColors() { - SkDEBUGCODE(sk_atomic_inc(&fColorLockCount);) - return fColors; - } + const SkPMColor* readColors() const { return fColors; } - /** - * Balancing call to lockColors(). + /** read16BitCache() returns the array of RGB16 colors that mirror the 32bit colors. */ - void unlockColors(); - - /** Similar to lockColors(), lock16BitCache() returns the array of - RGB16 colors that mirror the 32bit colors. However, this function - will return null if kColorsAreOpaque_Flag is not set. - Also, unlike lockColors(), the returned array here cannot be modified. - */ - const uint16_t* lock16BitCache(); - /** Balancing call to lock16BitCache(). - */ - void unlock16BitCache() { - SkASSERT(f16BitCacheLockCount > 0); - SkDEBUGCODE(f16BitCacheLockCount -= 1); - } + const uint16_t* read16BitCache() const; - explicit SkColorTable(SkFlattenableReadBuffer&); - void writeToBuffer(SkFlattenableWriteBuffer&) const; + void writeToBuffer(SkWriteBuffer&) const; + + // may return null + static SkColorTable* Create(SkReadBuffer&); private: - SkPMColor* fColors; - uint16_t* f16BitCache; - uint16_t fCount; - uint8_t fAlphaType; - SkDEBUGCODE(int fColorLockCount;) - SkDEBUGCODE(int f16BitCacheLockCount;) - - void inval16BitCache(); + enum AllocatedWithMalloc { + kAllocatedWithMalloc + }; + // assumes ownership of colors (assumes it was allocated w/ malloc) + SkColorTable(SkPMColor* colors, int count, AllocatedWithMalloc); + + SkPMColor* fColors; + mutable uint16_t* f16BitCache = nullptr; + mutable SkOnce f16BitCacheOnce; + int fCount; + + void init(const SkPMColor* colors, int count); + + friend class SkImageGenerator; + friend class SkBitmapRegionCodec; + // Only call if no other thread or cache has seen this table. + void dangerous_overwriteColors(const SkPMColor newColors[], int count) { + if (count < 0 || count > fCount) { + sk_throw(); + } + // assumes that f16BitCache nas NOT been initialized yet, so we don't try to update it + memcpy(fColors, newColors, count * sizeof(SkPMColor)); + fCount = count; // update fCount, in case count is smaller + } typedef SkRefCnt INHERITED; }; diff --git a/libskia/include/core/SkComposeShader.h b/libskia/include/core/SkComposeShader.h deleted file mode 100644 index 524161b7..00000000 --- a/libskia/include/core/SkComposeShader.h +++ /dev/null @@ -1,58 +0,0 @@ - -/* - * Copyright 2006 The Android Open Source Project - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - - -#ifndef SkComposeShader_DEFINED -#define SkComposeShader_DEFINED - -#include "SkShader.h" - -class SkXfermode; - -/////////////////////////////////////////////////////////////////////////////////////////// - -/** \class SkComposeShader - This subclass of shader returns the coposition of two other shaders, combined by - a xfermode. -*/ -class SK_API SkComposeShader : public SkShader { -public: - /** Create a new compose shader, given shaders A, B, and a combining xfermode mode. - When the xfermode is called, it will be given the result from shader A as its - "dst", and the result of from shader B as its "src". - mode->xfer32(sA_result, sB_result, ...) - @param shaderA The colors from this shader are seen as the "dst" by the xfermode - @param shaderB The colors from this shader are seen as the "src" by the xfermode - @param mode The xfermode that combines the colors from the two shaders. If mode - is null, then SRC_OVER is assumed. - */ - SkComposeShader(SkShader* sA, SkShader* sB, SkXfermode* mode = NULL); - virtual ~SkComposeShader(); - - virtual bool setContext(const SkBitmap&, const SkPaint&, - const SkMatrix&) SK_OVERRIDE; - virtual void endContext() SK_OVERRIDE; - virtual void shadeSpan(int x, int y, SkPMColor[], int count) SK_OVERRIDE; - - SK_DEVELOPER_TO_STRING() - SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkComposeShader) - -protected: - SkComposeShader(SkFlattenableReadBuffer& ); - virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE; - -private: - - SkShader* fShaderA; - SkShader* fShaderB; - SkXfermode* fMode; - - typedef SkShader INHERITED; -}; - -#endif diff --git a/libskia/include/core/SkData.h b/libskia/include/core/SkData.h index b5dc66fd..0622c9f0 100644 --- a/libskia/include/core/SkData.h +++ b/libskia/include/core/SkData.h @@ -1,4 +1,3 @@ - /* * Copyright 2011 Google Inc. * @@ -6,24 +5,22 @@ * found in the LICENSE file. */ - - #ifndef SkData_DEFINED #define SkData_DEFINED +#include + #include "SkRefCnt.h" -struct SkFILE; +class SkStream; /** * SkData holds an immutable data buffer. Not only is the data immutable, * but the actual ptr that is returned (by data() or bytes()) is guaranteed * to always be the same for the life of this instance. */ -class SK_API SkData : public SkRefCnt { +class SK_API SkData final : public SkNVRefCnt { public: - SK_DECLARE_INST_COUNT(SkData) - /** * Returns the number of bytes stored. */ @@ -44,6 +41,19 @@ class SK_API SkData : public SkRefCnt { return reinterpret_cast(fPtr); } + /** + * USE WITH CAUTION. + * This call will assert that the refcnt is 1, as a precaution against modifying the + * contents when another client/thread has access to the data. + */ + void* writable_data() { + if (fSize) { + // only assert we're unique if we're not empty + SkASSERT(this->unique()); + } + return fPtr; + } + /** * Helper to copy a range of the data into a caller-provided buffer. * Returns the actual number of bytes copied, after clamping offset and @@ -60,14 +70,21 @@ class SK_API SkData : public SkRefCnt { /** * Function that, if provided, will be called when the SkData goes out - * of scope, allowing for custom allocation/freeing of the data. + * of scope, allowing for custom allocation/freeing of the data's contents. */ - typedef void (*ReleaseProc)(const void* ptr, size_t length, void* context); + typedef void (*ReleaseProc)(const void* ptr, void* context); /** * Create a new dataref by copying the specified data */ - static SkData* NewWithCopy(const void* data, size_t length); + static sk_sp MakeWithCopy(const void* data, size_t length); + + + /** + * Create a new data with uninitialized contents. The caller should call writable_data() + * to write into the buffer, but this must be done before another ref() is made. + */ + static sk_sp MakeUninitialized(size_t length); /** * Create a new dataref by copying the specified c-string @@ -75,35 +92,42 @@ class SK_API SkData : public SkRefCnt { * equal to strlen(cstr) + 1. If cstr is NULL, it will be treated the same * as "". */ - static SkData* NewWithCString(const char cstr[]); + static sk_sp MakeWithCString(const char cstr[]); /** - * Create a new dataref, taking the data ptr as is, and using the + * Create a new dataref, taking the ptr as is, and using the * releaseproc to free it. The proc may be NULL. */ - static SkData* NewWithProc(const void* data, size_t length, - ReleaseProc proc, void* context); + static sk_sp MakeWithProc(const void* ptr, size_t length, ReleaseProc proc, void* ctx); + + /** + * Call this when the data parameter is already const and will outlive the lifetime of the + * SkData. Suitable for with const globals. + */ + static sk_sp MakeWithoutCopy(const void* data, size_t length) { + return MakeWithProc(data, length, DummyReleaseProc, nullptr); + } /** * Create a new dataref from a pointer allocated by malloc. The Data object * takes ownership of that allocation, and will handling calling sk_free. */ - static SkData* NewFromMalloc(const void* data, size_t length); + static sk_sp MakeFromMalloc(const void* data, size_t length); /** * Create a new dataref the file with the specified path. * If the file cannot be opened, this returns NULL. */ - static SkData* NewFromFileName(const char path[]); + static sk_sp MakeFromFileName(const char path[]); /** - * Create a new dataref from a SkFILE. - * This does not take ownership of the SkFILE, nor close it. - * The caller is free to close the SkFILE at its convenience. - * The SkFILE must be open for reading only. + * Create a new dataref from a stdio FILE. + * This does not take ownership of the FILE, nor close it. + * The caller is free to close the FILE at its convenience. + * The FILE must be open for reading only. * Returns NULL on failure. */ - static SkData* NewFromFILE(SkFILE* f); + static sk_sp MakeFromFILE(FILE* f); /** * Create a new dataref from a file descriptor. @@ -112,37 +136,50 @@ class SK_API SkData : public SkRefCnt { * The file descriptor must be open for reading only. * Returns NULL on failure. */ - static SkData* NewFromFD(int fd); + static sk_sp MakeFromFD(int fd); + + /** + * Attempt to read size bytes into a SkData. If the read succeeds, return the data, + * else return NULL. Either way the stream's cursor may have been changed as a result + * of calling read(). + */ + static sk_sp MakeFromStream(SkStream*, size_t size); /** * Create a new dataref using a subset of the data in the specified * src dataref. */ - static SkData* NewSubset(const SkData* src, size_t offset, size_t length); + static sk_sp MakeSubset(const SkData* src, size_t offset, size_t length); /** * Returns a new empty dataref (or a reference to a shared empty dataref). * New or shared, the caller must see that unref() is eventually called. */ - static SkData* NewEmpty(); + static sk_sp MakeEmpty(); private: + friend class SkNVRefCnt; ReleaseProc fReleaseProc; void* fReleaseProcContext; - - const void* fPtr; + void* fPtr; size_t fSize; SkData(const void* ptr, size_t size, ReleaseProc, void* context); - virtual ~SkData(); + explicit SkData(size_t size); // inplace new/delete + ~SkData(); + + // Ensure the unsized delete is called. + void operator delete(void* p) { ::operator delete(p); } // Called the first time someone calls NewEmpty to initialize the singleton. - static void NewEmptyImpl(SkData**); + friend SkData* sk_new_empty_data(); + + // shared internal factory + static sk_sp PrivateNewWithCopy(const void* srcOrNull, size_t length); + + static void DummyReleaseProc(const void*, void*); // {} typedef SkRefCnt INHERITED; }; -/** Typedef of SkAutoTUnref for automatically unref-ing a SkData. */ -typedef SkAutoTUnref SkAutoDataUnref; - #endif diff --git a/libskia/include/core/SkDataTable.h b/libskia/include/core/SkDataTable.h index 9440000e..0c92d7f5 100644 --- a/libskia/include/core/SkDataTable.h +++ b/libskia/include/core/SkDataTable.h @@ -8,10 +8,10 @@ #ifndef SkDataTable_DEFINED #define SkDataTable_DEFINED -#include "SkChunkAlloc.h" +#include "../private/SkChunkAlloc.h" +#include "../private/SkTDArray.h" #include "SkData.h" #include "SkString.h" -#include "SkTDArray.h" /** * Like SkData, SkDataTable holds an immutable data buffer. The data buffer is @@ -20,8 +20,6 @@ */ class SK_API SkDataTable : public SkRefCnt { public: - SK_DECLARE_INST_COUNT(SkDataTable) - /** * Returns true if the table is empty (i.e. has no entries). */ @@ -65,7 +63,7 @@ class SK_API SkDataTable : public SkRefCnt { typedef void (*FreeProc)(void* context); - static SkDataTable* NewEmpty(); + static sk_sp MakeEmpty(); /** * Return a new DataTable that contains a copy of the data stored in each @@ -76,8 +74,8 @@ class SK_API SkDataTable : public SkRefCnt { * ptrs[] array. * @param count the number of array elements in ptrs[] and sizes[] to copy. */ - static SkDataTable* NewCopyArrays(const void * const * ptrs, - const size_t sizes[], int count); + static sk_sp MakeCopyArrays(const void * const * ptrs, + const size_t sizes[], int count); /** * Return a new table that contains a copy of the data in array. @@ -87,11 +85,10 @@ class SK_API SkDataTable : public SkRefCnt { * @param count the number of entries to be copied out of array. The number * of bytes that will be copied is count * elemSize. */ - static SkDataTable* NewCopyArray(const void* array, size_t elemSize, - int count); + static sk_sp MakeCopyArray(const void* array, size_t elemSize, int count); - static SkDataTable* NewArrayProc(const void* array, size_t elemSize, - int count, FreeProc proc, void* context); + static sk_sp MakeArrayProc(const void* array, size_t elemSize, int count, + FreeProc proc, void* context); private: struct Dir { @@ -166,7 +163,7 @@ class SK_API SkDataTableBuilder : SkNoncopyable { * calls to append(). This call also clears any accumluated entries from * this builder, so its count() will be 0 after this call. */ - SkDataTable* detachDataTable(); + sk_sp detachDataTable(); private: SkTDArray fDir; diff --git a/libskia/include/core/SkDevice.h b/libskia/include/core/SkDevice.h index efb52cbb..b0aac41d 100644 --- a/libskia/include/core/SkDevice.h +++ b/libskia/include/core/SkDevice.h @@ -1,4 +1,3 @@ - /* * Copyright 2010 The Android Open Source Project * @@ -6,76 +5,47 @@ * found in the LICENSE file. */ - #ifndef SkDevice_DEFINED #define SkDevice_DEFINED #include "SkRefCnt.h" -#include "SkBitmap.h" #include "SkCanvas.h" #include "SkColor.h" -#include "SkDeviceProperties.h" +#include "SkSurfaceProps.h" +class SkBitmap; class SkClipStack; class SkDraw; +class SkDrawFilter; +class SkImageFilterCache; struct SkIRect; class SkMatrix; class SkMetaData; class SkRegion; - +class SkSpecialImage; class GrRenderTarget; class SK_API SkBaseDevice : public SkRefCnt { public: - SK_DECLARE_INST_COUNT(SkBaseDevice) - - /** - * Construct a new device. - */ - SkBaseDevice(); - /** * Construct a new device. */ - SkBaseDevice(const SkDeviceProperties& deviceProperties); - + explicit SkBaseDevice(const SkImageInfo&, const SkSurfaceProps&); virtual ~SkBaseDevice(); - /** - * Creates a device that is of the same type as this device (e.g. SW-raster, - * GPU, or PDF). The backing store for this device is created automatically - * (e.g. offscreen pixels or FBO or whatever is appropriate). - * - * @param width width of the device to create - * @param height height of the device to create - * @param isOpaque performance hint, set to true if you know that you will - * draw into this device such that all of the pixels will - * be opaque. - */ - SkBaseDevice* createCompatibleDevice(SkBitmap::Config config, - int width, int height, - bool isOpaque); - SkMetaData& getMetaData(); - enum Capabilities { - kGL_Capability = 0x1, //!< mask indicating GL support - kVector_Capability = 0x2, //!< mask indicating a vector representation - kAll_Capabilities = 0x3 - }; - virtual uint32_t getDeviceCapabilities() = 0; - - /** Return the width of the device (in pixels). - */ - virtual int width() const = 0; - /** Return the height of the device (in pixels). - */ - virtual int height() const = 0; + /** + * Return ImageInfo for this device. If the canvas is not backed by pixels + * (cpu or gpu), then the info's ColorType will be kUnknown_SkColorType. + */ + const SkImageInfo& imageInfo() const { return fInfo; } - /** Return the image properties of the device. */ - virtual const SkDeviceProperties& getDeviceProperties() const { - //Currently, all the properties are leaky. - return fLeakyProperties; + /** + * Return SurfaceProps for this device. + */ + const SkSurfaceProps& surfaceProps() const { + return fSurfaceProps; } /** @@ -89,17 +59,25 @@ class SK_API SkBaseDevice : public SkRefCnt { bounds->setXYWH(origin.x(), origin.y(), this->width(), this->height()); } + SkIRect getGlobalBounds() const { + SkIRect bounds; + this->getGlobalBounds(&bounds); + return bounds; + } - /** Returns true if the device's bitmap's config treats every pixel as - implicitly opaque. - */ - virtual bool isOpaque() const = 0; + int width() const { + return this->imageInfo().width(); + } - /** Return the bitmap config of the device's pixels - */ - SK_ATTR_DEPRECATED("want to hide configness of the device -- don't use") - virtual SkBitmap::Config config() const = 0; + int height() const { + return this->imageInfo().height(); + } + bool isOpaque() const { + return this->imageInfo().isOpaque(); + } + +#ifdef SK_SUPPORT_LEGACY_ACCESSBITMAP /** Return the bitmap associated with this device. Call this each time you need to access the bitmap, as it notifies the subclass to perform any flushing etc. before you examine the pixels. @@ -107,30 +85,26 @@ class SK_API SkBaseDevice : public SkRefCnt { @return the device's bitmap */ const SkBitmap& accessBitmap(bool changePixels); +#endif + + bool writePixels(const SkImageInfo&, const void*, size_t rowBytes, int x, int y); /** - * DEPRECATED: This will be made protected once WebKit stops using it. - * Instead use Canvas' writePixels method. - * - * Similar to draw sprite, this method will copy the pixels in bitmap onto - * the device, with the top/left corner specified by (x, y). The pixel - * values in the device are completely replaced: there is no blending. - * - * Currently if bitmap is backed by a texture this is a no-op. This may be - * relaxed in the future. + * Try to get write-access to the pixels behind the device. If successful, this returns true + * and fills-out the pixmap parameter. On success it also bumps the genID of the underlying + * bitmap. * - * If the bitmap has config kARGB_8888_Config then the config8888 param - * will determines how the pixel valuess are intepreted. If the bitmap is - * not kARGB_8888_Config then this parameter is ignored. + * On failure, returns false and ignores the pixmap parameter. */ - virtual void writePixels(const SkBitmap& bitmap, int x, int y, - SkCanvas::Config8888 config8888 = SkCanvas::kNative_Premul_Config8888) = 0; + bool accessPixels(SkPixmap* pmap); /** - * Return the device's associated gpu render target, or NULL. + * Try to get read-only-access to the pixels behind the device. If successful, this returns + * true and fills-out the pixmap parameter. + * + * On failure, returns false and ignores the pixmap parameter. */ - virtual GrRenderTarget* accessRenderTarget() = 0; - + bool peekPixels(SkPixmap*); /** * Return the device's origin: its offset in device coordinates from @@ -138,83 +112,23 @@ class SK_API SkBaseDevice : public SkRefCnt { */ const SkIPoint& getOrigin() const { return fOrigin; } - /** - * onAttachToCanvas is invoked whenever a device is installed in a canvas - * (i.e., setDevice, saveLayer (for the new device created by the save), - * and SkCanvas' SkBaseDevice & SkBitmap -taking ctors). It allows the - * devices to prepare for drawing (e.g., locking their pixels, etc.) - */ - virtual void onAttachToCanvas(SkCanvas*) { - SkASSERT(!fAttachedToCanvas); - this->lockPixels(); -#ifdef SK_DEBUG - fAttachedToCanvas = true; -#endif - }; - - /** - * onDetachFromCanvas notifies a device that it will no longer be drawn to. - * It gives the device a chance to clean up (e.g., unlock its pixels). It - * is invoked from setDevice (for the displaced device), restore and - * possibly from SkCanvas' dtor. - */ - virtual void onDetachFromCanvas() { - SkASSERT(fAttachedToCanvas); - this->unlockPixels(); -#ifdef SK_DEBUG - fAttachedToCanvas = false; -#endif - }; - protected: - enum Usage { - kGeneral_Usage, - kSaveLayer_Usage // clear(eraseColor); } + virtual bool onShouldDisableLCD(const SkPaint&) const { return false; } /** These are called inside the per-device-layer loop for each draw call. When these are called, we have already applied any saveLayer operations, @@ -226,11 +140,20 @@ class SK_API SkBaseDevice : public SkRefCnt { const SkPoint[], const SkPaint& paint) = 0; virtual void drawRect(const SkDraw&, const SkRect& r, const SkPaint& paint) = 0; + virtual void drawRegion(const SkDraw&, const SkRegion& r, + const SkPaint& paint); virtual void drawOval(const SkDraw&, const SkRect& oval, const SkPaint& paint) = 0; + /** By the time this is called we know that abs(sweepAngle) is in the range [0, 360). */ + virtual void drawArc(const SkDraw&, const SkRect& oval, SkScalar startAngle, + SkScalar sweepAngle, bool useCenter, const SkPaint& paint); virtual void drawRRect(const SkDraw&, const SkRRect& rr, const SkPaint& paint) = 0; + // Default impl calls drawPath() + virtual void drawDRRect(const SkDraw&, const SkRRect& outer, + const SkRRect& inner, const SkPaint&); + /** * If pathIsMutable, then the implementation is allowed to cast path to a * non-const pointer and modify it in place (as an optimization). Canvas @@ -258,7 +181,19 @@ class SK_API SkBaseDevice : public SkRefCnt { virtual void drawBitmapRect(const SkDraw&, const SkBitmap&, const SkRect* srcOrNull, const SkRect& dst, const SkPaint& paint, - SkCanvas::DrawBitmapRectFlags flags) = 0; + SkCanvas::SrcRectConstraint) = 0; + virtual void drawBitmapNine(const SkDraw&, const SkBitmap&, const SkIRect& center, + const SkRect& dst, const SkPaint&); + virtual void drawBitmapLattice(const SkDraw&, const SkBitmap&, const SkCanvas::Lattice&, + const SkRect& dst, const SkPaint&); + + virtual void drawImage(const SkDraw&, const SkImage*, SkScalar x, SkScalar y, const SkPaint&); + virtual void drawImageRect(const SkDraw&, const SkImage*, const SkRect* src, const SkRect& dst, + const SkPaint&, SkCanvas::SrcRectConstraint); + virtual void drawImageNine(const SkDraw&, const SkImage*, const SkIRect& center, + const SkRect& dst, const SkPaint&); + virtual void drawImageLattice(const SkDraw&, const SkImage*, const SkCanvas::Lattice&, + const SkRect& dst, const SkPaint&); /** * Does not handle text decoration. @@ -267,125 +202,124 @@ class SK_API SkBaseDevice : public SkRefCnt { virtual void drawText(const SkDraw&, const void* text, size_t len, SkScalar x, SkScalar y, const SkPaint& paint) = 0; virtual void drawPosText(const SkDraw&, const void* text, size_t len, - const SkScalar pos[], SkScalar constY, - int scalarsPerPos, const SkPaint& paint) = 0; - virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len, - const SkPath& path, const SkMatrix* matrix, - const SkPaint& paint) = 0; + const SkScalar pos[], int scalarsPerPos, + const SkPoint& offset, const SkPaint& paint) = 0; virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCount, const SkPoint verts[], const SkPoint texs[], - const SkColor colors[], SkXfermode* xmode, + const SkColor colors[], SkBlendMode, const uint16_t indices[], int indexCount, const SkPaint& paint) = 0; + // default implementation unrolls the blob runs. + virtual void drawTextBlob(const SkDraw&, const SkTextBlob*, SkScalar x, SkScalar y, + const SkPaint& paint, SkDrawFilter* drawFilter); + // default implementation calls drawVertices + virtual void drawPatch(const SkDraw&, const SkPoint cubics[12], const SkColor colors[4], + const SkPoint texCoords[4], SkBlendMode, const SkPaint& paint); + + // default implementation calls drawPath + virtual void drawAtlas(const SkDraw&, const SkImage* atlas, const SkRSXform[], const SkRect[], + const SkColor[], int count, SkBlendMode, const SkPaint&); + + virtual void drawAnnotation(const SkDraw&, const SkRect&, const char[], SkData*) {} + /** The SkDevice passed will be an SkDevice which was returned by a call to - onCreateCompatibleDevice on this device with kSaveLayer_Usage. + onCreateDevice on this device with kNeverTile_TileExpectation. */ virtual void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y, const SkPaint&) = 0; - // DEPRECATED -- will remove this once the subclass stop overriding it - virtual void drawPosTextOnPath(const SkDraw&, const void* text, size_t len, - const SkPoint pos[], const SkPaint&, - const SkPath&, const SkMatrix*) {} + virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len, const SkPath&, + const SkMatrix*, const SkPaint&); + virtual void drawTextRSXform(const SkDraw&, const void* text, size_t len, const SkRSXform[], + const SkPaint&); - // MM-2013-08-16: [[ RefactorGraphics ]] Expose drawDevMask. Used to render masks produced by platform specific text rendering procedures. - virtual void drawDevMask(const SkDraw&, const SkMask&, const SkPaint&) = 0; - - /** - * On success (returns true), copy the device pixels into the bitmap. - * On failure, the bitmap parameter is left unchanged and false is - * returned. - * - * The device's pixels are converted to the bitmap's config. The only - * supported config is kARGB_8888_Config, though this is likely to be - * relaxed in the future. The meaning of config kARGB_8888_Config is - * modified by the enum param config8888. The default value interprets - * kARGB_8888_Config as SkPMColor - * - * If the bitmap has pixels already allocated, the device pixels will be - * written there. If not, bitmap->allocPixels() will be called - * automatically. If the bitmap is backed by a texture readPixels will - * fail. - * - * The actual pixels written is the intersection of the device's bounds, - * and the rectangle formed by the bitmap's width,height and the specified - * x,y. If bitmap pixels extend outside of that intersection, they will not - * be modified. - * - * Other failure conditions: - * * If the device is not a raster device (e.g. PDF) then readPixels will - * fail. - * * If bitmap is texture-backed then readPixels will fail. (This may be - * relaxed in the future.) - */ - bool readPixels(SkBitmap* bitmap, - int x, int y, - SkCanvas::Config8888 config8888); + virtual void drawSpecial(const SkDraw&, SkSpecialImage*, int x, int y, const SkPaint&); + virtual sk_sp makeSpecial(const SkBitmap&); + virtual sk_sp makeSpecial(const SkImage*); + virtual sk_sp snapSpecial(); + + bool readPixels(const SkImageInfo&, void* dst, size_t rowBytes, int x, int y); /////////////////////////////////////////////////////////////////////////// +#ifdef SK_SUPPORT_LEGACY_ACCESSBITMAP /** Update as needed the pixel value in the bitmap, so that the caller can access the pixels directly. @return The device contents as a bitmap */ - virtual const SkBitmap& onAccessBitmap() = 0; + virtual const SkBitmap& onAccessBitmap() { + SkASSERT(0); + return fLegacyBitmap; + } +#endif - /** - * Implements readPixels API. The caller will ensure that: - * 1. bitmap has pixel config kARGB_8888_Config. - * 2. bitmap has pixels. - * 3. The rectangle (x, y, x + bitmap->width(), y + bitmap->height()) is - * contained in the device bounds. - */ - virtual bool onReadPixels(const SkBitmap& bitmap, - int x, int y, - SkCanvas::Config8888 config8888) = 0; + virtual GrContext* context() const { return nullptr; } - /** Called when this device is installed into a Canvas. Balanced by a call - to unlockPixels() when the device is removed from a Canvas. - */ - virtual void lockPixels() = 0; - virtual void unlockPixels() = 0; + virtual sk_sp makeSurface(const SkImageInfo&, const SkSurfaceProps&); + virtual bool onPeekPixels(SkPixmap*) { return false; } /** - * Returns true if the device allows processing of this imagefilter. If - * false is returned, then the filter is ignored. This may happen for - * some subclasses that do not support pixel manipulations after drawing - * has occurred (e.g. printing). The default implementation returns true. + * The caller is responsible for "pre-clipping" the dst. The impl can assume that the dst + * image at the specified x,y offset will fit within the device's bounds. + * + * This is explicitly asserted in readPixels(), the public way to call this. */ - virtual bool allowImageFilter(SkImageFilter*) = 0; + virtual bool onReadPixels(const SkImageInfo&, void*, size_t, int x, int y); /** - * Override and return true for filters that the device can handle - * intrinsically. Doing so means that SkCanvas will pass-through this - * filter to drawSprite and drawDevice (and potentially filterImage). - * Returning false means the SkCanvas will have apply the filter itself, - * and just pass the resulting image to the device. + * The caller is responsible for "pre-clipping" the src. The impl can assume that the src + * image at the specified x,y offset will fit within the device's bounds. + * + * This is explicitly asserted in writePixelsDirect(), the public way to call this. */ - virtual bool canHandleImageFilter(SkImageFilter*) = 0; + virtual bool onWritePixels(const SkImageInfo&, const void*, size_t, int x, int y); + + virtual bool onAccessPixels(SkPixmap*) { return false; } + + struct CreateInfo { + static SkPixelGeometry AdjustGeometry(const SkImageInfo&, TileUsage, SkPixelGeometry, + bool preserveLCDText); + + // The constructor may change the pixel geometry based on other parameters. + CreateInfo(const SkImageInfo& info, + TileUsage tileUsage, + SkPixelGeometry geo) + : fInfo(info) + , fTileUsage(tileUsage) + , fPixelGeometry(AdjustGeometry(info, tileUsage, geo, false)) + {} + + CreateInfo(const SkImageInfo& info, + TileUsage tileUsage, + SkPixelGeometry geo, + bool preserveLCDText) + : fInfo(info) + , fTileUsage(tileUsage) + , fPixelGeometry(AdjustGeometry(info, tileUsage, geo, preserveLCDText)) + {} + + const SkImageInfo fInfo; + const TileUsage fTileUsage; + const SkPixelGeometry fPixelGeometry; + }; /** - * Related (but not required) to canHandleImageFilter, this method returns - * true if the device could apply the filter to the src bitmap and return - * the result (and updates offset as needed). - * If the device does not recognize or support this filter, - * it just returns false and leaves result and offset unchanged. + * Create a new device based on CreateInfo. If the paint is not null, then it represents a + * preview of how the new device will be composed with its creator device (this). + * + * The subclass may be handed this device in drawDevice(), so it must always return + * a device that it knows how to draw, and that it knows how to identify if it is not of the + * same subclass (since drawDevice is passed a SkBaseDevice*). If the subclass cannot fulfill + * that contract (e.g. PDF cannot support some settings on the paint) it should return NULL, + * and the caller may then decide to explicitly create a bitmapdevice, knowing that later + * it could not call drawDevice with it (but it could call drawSprite or drawBitmap). */ - virtual bool filterImage(SkImageFilter*, const SkBitmap&, const SkMatrix&, - SkBitmap* result, SkIPoint* offset) = 0; - - // This is equal kBGRA_Premul_Config8888 or kRGBA_Premul_Config8888 if - // either is identical to kNative_Premul_Config8888. Otherwise, -1. - static const SkCanvas::Config8888 kPMColorAlias; + virtual SkBaseDevice* onCreateDevice(const CreateInfo&, const SkPaint*) { + return NULL; + } -protected: - /** - * Leaky properties are those which the device should be applying but it isn't. - * These properties will be applied by the draw, when and as it can. - * If the device does handle a property, that property should be set to the identity value - * for that property, effectively making it non-leaky. - */ - SkDeviceProperties fLeakyProperties; + // A helper function used by derived classes to log the scale factor of a bitmap or image draw. + static void LogDrawScaleFactor(const SkMatrix&, SkFilterQuality); private: friend class SkCanvas; @@ -393,40 +327,48 @@ class SK_API SkBaseDevice : public SkRefCnt { friend class SkDraw; friend class SkDrawIter; friend class SkDeviceFilteredPaint; - friend class SkDeviceImageFilterProxy; - + friend class SkNoPixelsBitmapDevice; friend class SkSurface_Raster; + friend class DeviceTestingAccess; // used to change the backend's pixels (and possibly config/rowbytes) // but cannot change the width/height, so there should be no change to // any clip information. // TODO: move to SkBitmapDevice - virtual void replaceBitmapBackendForRasterSurface(const SkBitmap&) = 0; + virtual void replaceBitmapBackendForRasterSurface(const SkBitmap&) {} - // just called by SkCanvas when built as a layer - void setOrigin(int x, int y) { fOrigin.set(x, y); } - // just called by SkCanvas for saveLayer - SkBaseDevice* createCompatibleDeviceForSaveLayer(SkBitmap::Config config, - int width, int height, - bool isOpaque); + virtual bool forceConservativeRasterClip() const { return false; } /** - * Subclasses should override this to implement createCompatibleDevice. + * Don't call this! */ - virtual SkBaseDevice* onCreateCompatibleDevice(SkBitmap::Config config, - int width, int height, - bool isOpaque, - Usage usage) = 0; + virtual GrRenderTargetContext* accessRenderTargetContext() { return nullptr; } + + // just called by SkCanvas when built as a layer + void setOrigin(int x, int y) { fOrigin.set(x, y); } /** Causes any deferred drawing to the device to be completed. */ - virtual void flush() = 0; + virtual void flush() {} + + virtual SkImageFilterCache* getImageFilterCache() { return NULL; } + + friend class SkBitmapDevice; + void privateResize(int w, int h) { + *const_cast(&fInfo) = fInfo.makeWH(w, h); + } + + bool drawExternallyScaledImage(const SkDraw& draw, const SkImage* image, const SkRect* src, + const SkRect& dst, const SkPaint& paint, + SkCanvas::SrcRectConstraint constraint); SkIPoint fOrigin; SkMetaData* fMetaData; + const SkImageInfo fInfo; + const SkSurfaceProps fSurfaceProps; -#ifdef SK_DEBUG - bool fAttachedToCanvas; +#ifdef SK_SUPPORT_LEGACY_ACCESSBITMAP + SkBitmap fLegacyBitmap; #endif typedef SkRefCnt INHERITED; diff --git a/libskia/include/core/SkDeviceProperties.h b/libskia/include/core/SkDeviceProperties.h deleted file mode 100644 index fd573f41..00000000 --- a/libskia/include/core/SkDeviceProperties.h +++ /dev/null @@ -1,112 +0,0 @@ -#ifndef SkDeviceProperties_DEFINED -#define SkDeviceProperties_DEFINED - -#ifndef SK_GAMMA_EXPONENT - #define SK_GAMMA_EXPONENT (2.2f) -#endif - -#ifdef SK_GAMMA_SRGB - #undef SK_GAMMA_EXPONENT - #define SK_GAMMA_EXPONENT (0.0f) -#endif - -//TODO: get everyone to stop using SkFontLCDConfig::SetSubpixel* and remove this import. -#include "SkFontLCDConfig.h" - -struct SkDeviceProperties { - struct Geometry { - /** The orientation of the pixel specifies the interpretation of the - * layout. If the orientation is horizontal, the layout is interpreted as - * left to right. It the orientation is vertical, the layout is - * interpreted top to bottom (rotated 90deg cw from horizontal). - */ - enum Orientation { - kUnknown_Orientation = 0x0, - kKnown_Orientation = 0x2, - - kHorizontal_Orientation = 0x2, //!< this is the default - kVertical_Orientation = 0x3, - - kOrientationMask = 0x3, - }; - - /** The layout of the pixel specifies its subpixel geometry. - * - * kUnknown_Layout means that the subpixel elements are not spatially - * separated in any known or usable fashion. - */ - enum Layout { - kUnknown_Layout = 0x0, - kKnown_Layout = 0x8, - - kRGB_Layout = 0x8, //!< this is the default - kBGR_Layout = 0xC, - - kLayoutMask = 0xC, - }; - - Orientation getOrientation() { - return static_cast(fGeometry & kOrientationMask); - } - Layout getLayout() { - return static_cast(fGeometry & kLayoutMask); - } - - bool isOrientationKnown() { - return SkToBool(fGeometry & kKnown_Orientation); - } - bool isLayoutKnown() { - return SkToBool(fGeometry & kKnown_Layout); - } - - private: - //TODO: get everyone to stop using SkFontLCDConfig::SetSubpixel* and replace these calls with constants. - static Orientation fromOldOrientation(SkFontLCDConfig::LCDOrientation orientation) { - switch (orientation) { - case SkFontLCDConfig::kHorizontal_LCDOrientation: return kHorizontal_Orientation; - case SkFontLCDConfig::kVertical_LCDOrientation: return kVertical_Orientation; - default: return kUnknown_Orientation; - } - } - static Layout fromOldLayout(SkFontLCDConfig::LCDOrder order) { - switch (order) { - case SkFontLCDConfig::kRGB_LCDOrder: return kRGB_Layout; - case SkFontLCDConfig::kBGR_LCDOrder: return kBGR_Layout; - default: return kUnknown_Layout; - } - } - public: - static Geometry MakeDefault() { - Orientation orientation = fromOldOrientation(SkFontLCDConfig::GetSubpixelOrientation()); //kHorizontal_Orientation - Layout layout = fromOldLayout(SkFontLCDConfig::GetSubpixelOrder()); //kRGB_Layout - Geometry ret = { SkToU8(orientation | layout) }; - return ret; - } - - static Geometry Make(Orientation orientation, Layout layout) { - Geometry ret = { SkToU8(orientation | layout) }; - return ret; - } - - uint8_t fGeometry; - }; - - static SkDeviceProperties MakeDefault() { - SkDeviceProperties ret = { Geometry::MakeDefault(), SK_GAMMA_EXPONENT }; - return ret; - } - - static SkDeviceProperties Make(Geometry geometry, SkScalar gamma) { - SkDeviceProperties ret = { geometry, gamma }; - return ret; - } - - /** Each pixel of an image will have some number of channels. - * Can the layout of those channels be exploited? */ - Geometry fGeometry; - - /** Represents the color space of the image. This is a woefully inadequate beginning. */ - SkScalar fGamma; -}; - -#endif diff --git a/libskia/include/core/SkDocument.h b/libskia/include/core/SkDocument.h index dbf4bc59..418a8374 100644 --- a/libskia/include/core/SkDocument.h +++ b/libskia/include/core/SkDocument.h @@ -10,8 +10,11 @@ #include "SkBitmap.h" #include "SkPicture.h" +#include "SkPixelSerializer.h" #include "SkRect.h" #include "SkRefCnt.h" +#include "SkString.h" +#include "SkTime.h" class SkCanvas; class SkWStream; @@ -30,55 +33,127 @@ class SkWStream; * c. doc->endPage(); * 3. Close the document with doc->close(). */ -class SkDocument : public SkRefCnt { +class SK_API SkDocument : public SkRefCnt { public: - SK_DECLARE_INST_COUNT(SkDocument) + struct OptionalTimestamp { + SkTime::DateTime fDateTime; + bool fEnabled; + OptionalTimestamp() : fEnabled(false) {} + }; /** - * Create a PDF-backed document, writing the results into a file. - * If there is an error trying to create the doc, returns NULL. - * encoder sets the DCTEncoder for images, to encode a bitmap - * as JPEG (DCT). - * rasterDpi - the DPI at which features without native PDF support - * will be rasterized (e.g. draw image with perspective, - * draw text with perspective, ...) - * A larger DPI would create a PDF that reflects the original - * intent with better fidelity, but it can make for larger - * PDF files too, which would use more memory while rendering, - * and it would be slower to be processed or sent online or - * to printer. + * Optional metadata to be passed into the PDF factory function. */ - static SkDocument* CreatePDF( - const char filename[], - SkPicture::EncodeBitmap encoder = NULL, - SkScalar rasterDpi = SK_ScalarDefaultRasterDPI); + struct PDFMetadata { + /** + * The document’s title. + */ + SkString fTitle; + /** + * The name of the person who created the document. + */ + SkString fAuthor; + /** + * The subject of the document. + */ + SkString fSubject; + /** + * Keywords associated with the document. Commas may be used + * to delineate keywords within the string. + */ + SkString fKeywords; + /** + * If the document was converted to PDF from another format, + * the name of the conforming product that created the + * original document from which it was converted. + */ + SkString fCreator; + /** + * The product that is converting this document to PDF. + * + * Leave fProducer empty to get the default, correct value. + */ + SkString fProducer; + /** + * The date and time the document was created. + */ + OptionalTimestamp fCreation; + /** + * The date and time the document was most recently modified. + */ + OptionalTimestamp fModified; + }; /** - * Create a PDF-backed document, writing the results into a stream. - * If there is an error trying to create the doc, returns NULL. + * Create a PDF-backed document, writing the results into a + * SkWStream. + * + * PDF pages are sized in point units. 1 pt == 1/72 inch == + * 127/360 mm. + * + * @param stream A PDF document will be written to this + * stream. The document may write to the stream at + * anytime during its lifetime, until either close() is + * called or the document is deleted. + * @param dpi The DPI (pixels-per-inch) at which features without + * native PDF support will be rasterized (e.g. draw image + * with perspective, draw text with perspective, ...) A + * larger DPI would create a PDF that reflects the + * original intent with better fidelity, but it can make + * for larger PDF files too, which would use more memory + * while rendering, and it would be slower to be processed + * or sent online or to printer. + * @param metadata a PDFmetadata object. Any fields may be left + * empty. + * @param jpegEncoder For PDF documents, if a jpegEncoder is set, + * use it to encode SkImages and SkBitmaps as [JFIF]JPEGs. + * This feature is deprecated and is only supplied for + * backwards compatability. + * The prefered method to create PDFs with JPEG images is + * to use SkImage::NewFromEncoded() and not jpegEncoder. + * Chromium uses NewFromEncoded. + * If the encoder is unset, or if jpegEncoder->onEncode() + * returns NULL, fall back on encoding images losslessly + * with Deflate. + * @param pdfa Iff true, include XMP metadata, a document UUID, + * and sRGB output intent information. This adds length + * to the document and makes it non-reproducable, but are + * necessary features for PDF/A-2b conformance * - * The document may write to the stream at anytime during its lifetime, - * until either close() is called or the document is deleted. Once close() - * has been called, and all of the data has been written to the stream, - * if there is a Done proc provided, it will be called with the stream. - * The proc can delete the stream, or whatever it needs to do. - * encoder sets the DCTEncoder for images, to encode a bitmap - * as JPEG (DCT). - * Done - clean up method intended to allow deletion of the stream. - * Its aborted parameter is true if the cleanup is due to an abort - * call. It is false otherwise. - * rasterDpi - the DPI at which features without native PDF support - * will be rasterized (e.g. draw image with perspective, - * draw text with perspective, ...) - * A larger DPI would create a PDF that reflects the original - * intent with better fidelity, but it can make for larger - * PDF files too, which would use more memory while rendering, - * and it would be slower to be processed or sent online or - * to printer. */ - static SkDocument* CreatePDF( - SkWStream*, void (*Done)(SkWStream*,bool aborted) = NULL, - SkPicture::EncodeBitmap encoder = NULL, - SkScalar rasterDpi = SK_ScalarDefaultRasterDPI); + * @returns NULL if there is an error, otherwise a newly created + * PDF-backed SkDocument. + */ + static sk_sp MakePDF(SkWStream* stream, + SkScalar dpi, + const SkDocument::PDFMetadata& metadata, + sk_sp jpegEncoder, + bool pdfa); + + static sk_sp MakePDF(SkWStream* stream, + SkScalar dpi = SK_ScalarDefaultRasterDPI) { + return SkDocument::MakePDF(stream, dpi, SkDocument::PDFMetadata(), + nullptr, false); + } + + /** + * Create a PDF-backed document, writing the results into a file. + */ + static sk_sp MakePDF(const char outputFilePath[], + SkScalar dpi = SK_ScalarDefaultRasterDPI); + + /** + * Create a XPS-backed document, writing the results into the stream. + * Returns NULL if XPS is not supported. + */ + static sk_sp MakeXPS(SkWStream* stream, + SkScalar dpi = SK_ScalarDefaultRasterDPI); + + /** + * Create a XPS-backed document, writing the results into a file. + * Returns NULL if XPS is not supported. + */ + static sk_sp MakeXPS(const char path[], + SkScalar dpi = SK_ScalarDefaultRasterDPI); /** * Begin a new page for the document, returning the canvas that will draw @@ -100,9 +175,8 @@ class SkDocument : public SkRefCnt { * or stream holding the document's contents. After close() the document * can no longer add new pages. Deleting the document will automatically * call close() if need be. - * Returns true on success or false on failure. */ - bool close(); + void close(); /** * Call abort() to stop producing the document immediately. @@ -112,6 +186,7 @@ class SkDocument : public SkRefCnt { protected: SkDocument(SkWStream*, void (*)(SkWStream*, bool aborted)); + // note: subclasses must call close() in their destructor, as the base class // cannot do this for them. virtual ~SkDocument(); @@ -119,9 +194,12 @@ class SkDocument : public SkRefCnt { virtual SkCanvas* onBeginPage(SkScalar width, SkScalar height, const SkRect& content) = 0; virtual void onEndPage() = 0; - virtual bool onClose(SkWStream*) = 0; + virtual void onClose(SkWStream*) = 0; virtual void onAbort() = 0; + // Allows subclasses to write to the stream as pages are written. + SkWStream* getStream() { return fStream; } + enum State { kBetweenPages_State, kInPage_State, diff --git a/libskia/include/core/SkDraw.h b/libskia/include/core/SkDraw.h index edfe2203..8a2c2d44 100644 --- a/libskia/include/core/SkDraw.h +++ b/libskia/include/core/SkDraw.h @@ -13,11 +13,12 @@ #include "SkCanvas.h" #include "SkMask.h" #include "SkPaint.h" +#include "SkStrokeRec.h" class SkBitmap; -class SkBounder; class SkClipStack; class SkBaseDevice; +class SkBlitter; class SkMatrix; class SkPath; class SkRegion; @@ -29,12 +30,15 @@ class SkRRect; class SkDraw { public: SkDraw(); - SkDraw(const SkDraw& src); void drawPaint(const SkPaint&) const; void drawPoints(SkCanvas::PointMode, size_t count, const SkPoint[], const SkPaint&, bool forceUseDevice = false) const; - void drawRect(const SkRect&, const SkPaint&) const; + void drawRect(const SkRect& prePaintRect, const SkPaint&, const SkMatrix* paintMatrix, + const SkRect* postPaintRect) const; + void drawRect(const SkRect& rect, const SkPaint& paint) const { + this->drawRect(rect, paint, NULL, NULL); + } void drawRRect(const SkRRect&, const SkPaint&) const; /** * To save on mallocs, we allow a flag that tells us that srcPath is @@ -50,22 +54,23 @@ class SkDraw { this->drawPath(path, paint, prePathMatrix, pathIsMutable, false); } - void drawPath(const SkPath& path, const SkPaint& paint) const { - this->drawPath(path, paint, NULL, false, false); + void drawPath(const SkPath& path, const SkPaint& paint, + SkBlitter* customBlitter = NULL) const { + this->drawPath(path, paint, NULL, false, false, customBlitter); } - void drawBitmap(const SkBitmap&, const SkMatrix&, const SkPaint&) const; + /* If dstOrNull is null, computes a dst by mapping the bitmap's bounds through the matrix. */ + void drawBitmap(const SkBitmap&, const SkMatrix&, const SkRect* dstOrNull, + const SkPaint&) const; void drawSprite(const SkBitmap&, int x, int y, const SkPaint&) const; void drawText(const char text[], size_t byteLength, SkScalar x, SkScalar y, const SkPaint& paint) const; void drawPosText(const char text[], size_t byteLength, - const SkScalar pos[], SkScalar constY, - int scalarsPerPosition, const SkPaint& paint) const; - void drawTextOnPath(const char text[], size_t byteLength, - const SkPath&, const SkMatrix*, const SkPaint&) const; + const SkScalar pos[], int scalarsPerPosition, + const SkPoint& offset, const SkPaint& paint) const; void drawVertices(SkCanvas::VertexMode mode, int count, const SkPoint vertices[], const SkPoint textures[], - const SkColor colors[], SkXfermode* xmode, + const SkColor colors[], SkBlendMode bmode, const uint16_t indices[], int ptCount, const SkPaint& paint) const; @@ -75,8 +80,9 @@ class SkDraw { * * Only device A8 is supported right now. */ - void drawPathCoverage(const SkPath& src, const SkPaint& paint) const { - this->drawPath(src, paint, NULL, false, true); + void drawPathCoverage(const SkPath& src, const SkPaint& paint, + SkBlitter* customBlitter = NULL) const { + this->drawPath(src, paint, NULL, false, true, customBlitter); } /** Helper function that creates a mask from a path and an optional maskfilter. @@ -87,7 +93,7 @@ class SkDraw { static bool DrawToMask(const SkPath& devPath, const SkIRect* clipBounds, const SkMaskFilter*, const SkMatrix* filterMatrix, SkMask* mask, SkMask::CreateMode mode, - SkPaint::Style style); + SkStrokeRec::InitStyle style); enum RectType { kHair_RectType, @@ -111,19 +117,20 @@ class SkDraw { void drawText_asPaths(const char text[], size_t byteLength, SkScalar x, SkScalar y, const SkPaint&) const; void drawPosText_asPaths(const char text[], size_t byteLength, - const SkScalar pos[], SkScalar constY, - int scalarsPerPosition, const SkPaint&) const; - - // MM-2013-08-16: [[ RefactorGraphics ]] Expose drawDevMask. Used to render masks produced by platform specific text rendering procedures. - void drawDevMask(const SkMask& mask, const SkPaint&) const; - + const SkScalar pos[], int scalarsPerPosition, + const SkPoint& offset, const SkPaint&) const; + static SkScalar ComputeResScaleForStroking(const SkMatrix& ); private: - //void drawDevMask(const SkMask& mask, const SkPaint&) const; + void drawDevMask(const SkMask& mask, const SkPaint&) const; void drawBitmapAsMask(const SkBitmap&, const SkPaint&) const; void drawPath(const SkPath&, const SkPaint&, const SkMatrix* preMatrix, - bool pathIsMutable, bool drawCoverage) const; + bool pathIsMutable, bool drawCoverage, + SkBlitter* customBlitter = NULL) const; + void drawLine(const SkPoint[2], const SkPaint&) const; + void drawDevPath(const SkPath& devPath, const SkPaint& paint, bool drawCoverage, + SkBlitter* customBlitter, bool doFill) const; /** * Return the current clip bounds, in local coordinates, with slop to account * for antialiasing or hairlines (i.e. device-bounds outset by 1, and then @@ -135,16 +142,16 @@ class SkDraw { bool SK_WARN_UNUSED_RESULT computeConservativeLocalClipBounds(SkRect* bounds) const; + /** Returns the current setting for using fake gamma and contrast. */ + uint32_t SK_WARN_UNUSED_RESULT scalerContextFlags() const; + public: - const SkBitmap* fBitmap; // required + SkPixmap fDst; const SkMatrix* fMatrix; // required - const SkRegion* fClip; // DEPRECATED const SkRasterClip* fRC; // required - const SkClipStack* fClipStack; // optional - SkBaseDevice* fDevice; // optional - SkBounder* fBounder; // optional - SkDrawProcs* fProcs; // optional + const SkClipStack* fClipStack; // optional, may be null + SkBaseDevice* fDevice; // optional, may be null #ifdef SK_DEBUG void validate() const; diff --git a/libskia/include/core/SkDrawFilter.h b/libskia/include/core/SkDrawFilter.h index 52cbba9d..2812017b 100644 --- a/libskia/include/core/SkDrawFilter.h +++ b/libskia/include/core/SkDrawFilter.h @@ -16,6 +16,8 @@ class SkCanvas; class SkPaint; /** + * DEPRECATED - use SkPaintFilterCanvas instead. + * * Right before something is being draw, filter() is called with the * paint. The filter may modify the paint as it wishes, which will then be * used for the actual drawing. Note: this modification only lasts for the @@ -23,8 +25,6 @@ class SkPaint; */ class SK_API SkDrawFilter : public SkRefCnt { public: - SK_DECLARE_INST_COUNT(SkDrawFilter) - enum Type { kPaint_Type, kPoint_Type, diff --git a/libskia/include/core/SkDrawLooper.h b/libskia/include/core/SkDrawLooper.h index d6028ff9..28d7d8be 100644 --- a/libskia/include/core/SkDrawLooper.h +++ b/libskia/include/core/SkDrawLooper.h @@ -10,7 +10,10 @@ #ifndef SkDrawLooper_DEFINED #define SkDrawLooper_DEFINED +#include "SkBlurTypes.h" #include "SkFlattenable.h" +#include "SkPoint.h" +#include "SkColor.h" class SkCanvas; class SkPaint; @@ -27,27 +30,50 @@ class SkString; */ class SK_API SkDrawLooper : public SkFlattenable { public: - SK_DECLARE_INST_COUNT(SkDrawLooper) - /** - * Called right before something is being drawn. This will be followed by - * calls to next() until next() returns false. + * Holds state during a draw. Users call next() until it returns false. + * + * Subclasses of SkDrawLooper should create a subclass of this object to + * hold state specific to their subclass. */ - virtual void init(SkCanvas*) = 0; + class SK_API Context : ::SkNoncopyable { + public: + Context() {} + virtual ~Context() {} + + /** + * Called in a loop on objects returned by SkDrawLooper::createContext(). + * Each time true is returned, the object is drawn (possibly with a modified + * canvas and/or paint). When false is finally returned, drawing for the object + * stops. + * + * On each call, the paint will be in its original state, but the + * canvas will be as it was following the previous call to next() or + * createContext(). + * + * The implementation must ensure that, when next() finally returns + * false, the canvas has been restored to the state it was + * initially, before createContext() was first called. + */ + virtual bool next(SkCanvas* canvas, SkPaint* paint) = 0; + }; /** - * Called in a loop (after init()). Each time true is returned, the object - * is drawn (possibly with a modified canvas and/or paint). When false is - * finally returned, drawing for the object stops. - * - * On each call, the paint will be in its original state, but the canvas - * will be as it was following the previous call to next() or init(). - * - * The implementation must ensure that, when next() finally returns false, - * that the canvas has been restored to the state it was initially, before - * init() was first called. + * Called right before something is being drawn. Returns a Context + * whose next() method should be called until it returns false. + * The caller has to ensure that the storage pointer provides enough + * memory for the Context. The required size can be queried by calling + * contextSize(). It is also the caller's responsibility to destroy the + * object after use. */ - virtual bool next(SkCanvas*, SkPaint* paint) = 0; + virtual Context* createContext(SkCanvas*, void* storage) const = 0; + + /** + * Returns the number of bytes needed to store subclasses of Context (belonging to the + * corresponding SkDrawLooper subclass). + */ + virtual size_t contextSize() const = 0; + /** * The fast bounds functions are used to enable the paint to be culled early @@ -59,16 +85,32 @@ class SK_API SkDrawLooper : public SkFlattenable { * storage rect, where the storage rect is with the union of the src rect * and the looper's bounding rect. */ - virtual bool canComputeFastBounds(const SkPaint& paint); - virtual void computeFastBounds(const SkPaint& paint, - const SkRect& src, SkRect* dst); + bool canComputeFastBounds(const SkPaint& paint) const; + void computeFastBounds(const SkPaint& paint, const SkRect& src, SkRect* dst) const; + + struct BlurShadowRec { + SkScalar fSigma; + SkVector fOffset; + SkColor fColor; + SkBlurStyle fStyle; + SkBlurQuality fQuality; + }; + /** + * If this looper can be interpreted as having two layers, such that + * 1. The first layer (bottom most) just has a blur and translate + * 2. The second layer has no modifications to either paint or canvas + * 3. No other layers. + * then return true, and if not null, fill out the BlurShadowRec). + * + * If any of the above are not met, return false and ignore the BlurShadowRec parameter. + */ + virtual bool asABlurShadow(BlurShadowRec*) const; - SkDEVCODE(virtual void toString(SkString* str) const = 0;) + SK_TO_STRING_PUREVIRT() SK_DEFINE_FLATTENABLE_TYPE(SkDrawLooper) protected: SkDrawLooper() {} - SkDrawLooper(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {} private: typedef SkFlattenable INHERITED; diff --git a/libskia/include/core/SkDrawable.h b/libskia/include/core/SkDrawable.h new file mode 100644 index 00000000..6fec3fcf --- /dev/null +++ b/libskia/include/core/SkDrawable.h @@ -0,0 +1,81 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkDrawable_DEFINED +#define SkDrawable_DEFINED + +#include "SkFlattenable.h" + +class SkCanvas; +class SkMatrix; +class SkPicture; +struct SkRect; + +/** + * Base-class for objects that draw into SkCanvas. + * + * The object has a generation ID, which is guaranteed to be unique across all drawables. To + * allow for clients of the drawable that may want to cache the results, the drawable must + * change its generation ID whenever its internal state changes such that it will draw differently. + */ +class SkDrawable : public SkFlattenable { +public: + SkDrawable(); + + /** + * Draws into the specified content. The drawing sequence will be balanced upon return + * (i.e. the saveLevel() on the canvas will match what it was when draw() was called, + * and the current matrix and clip settings will not be changed. + */ + void draw(SkCanvas*, const SkMatrix* = NULL); + void draw(SkCanvas*, SkScalar x, SkScalar y); + + SkPicture* newPictureSnapshot(); + + /** + * Return a unique value for this instance. If two calls to this return the same value, + * it is presumed that calling the draw() method will render the same thing as well. + * + * Subclasses that change their state should call notifyDrawingChanged() to ensure that + * a new value will be returned the next time it is called. + */ + uint32_t getGenerationID(); + + /** + * Return the (conservative) bounds of what the drawable will draw. If the drawable can + * change what it draws (e.g. animation or in response to some external change), then this + * must return a bounds that is always valid for all possible states. + */ + SkRect getBounds(); + + /** + * Calling this invalidates the previous generation ID, and causes a new one to be computed + * the next time getGenerationID() is called. Typically this is called by the object itself, + * in response to its internal state changing. + */ + void notifyDrawingChanged(); + + SK_DEFINE_FLATTENABLE_TYPE(SkDrawable) + Factory getFactory() const override { return nullptr; } + +protected: + virtual SkRect onGetBounds() = 0; + virtual void onDraw(SkCanvas*) = 0; + + /** + * Default implementation calls onDraw() with a canvas that records into a picture. Subclasses + * may override if they have a more efficient way to return a picture for the current state + * of their drawable. Note: this picture must draw the same as what would be drawn from + * onDraw(). + */ + virtual SkPicture* onNewPictureSnapshot(); + +private: + int32_t fGenerationID; +}; + +#endif diff --git a/libskia/include/core/SkEmptyShader.h b/libskia/include/core/SkEmptyShader.h deleted file mode 100644 index 08c131db..00000000 --- a/libskia/include/core/SkEmptyShader.h +++ /dev/null @@ -1,43 +0,0 @@ - -/* - * Copyright 2011 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - - - -#ifndef SkEmptyShader_DEFINED -#define SkEmptyShader_DEFINED - -#include "SkShader.h" - -/** - * \class SkEmptyShader - * A Shader that always draws nothing. Its setContext always returns false, - * so it never expects that its shadeSpan() methods will get called. - */ -class SK_API SkEmptyShader : public SkShader { -public: - SkEmptyShader() {} - - virtual uint32_t getFlags() SK_OVERRIDE; - virtual uint8_t getSpan16Alpha() const SK_OVERRIDE; - virtual bool setContext(const SkBitmap&, const SkPaint&, - const SkMatrix&) SK_OVERRIDE; - virtual void shadeSpan(int x, int y, SkPMColor span[], int count) SK_OVERRIDE; - virtual void shadeSpan16(int x, int y, uint16_t span[], int count) SK_OVERRIDE; - virtual void shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) SK_OVERRIDE; - - SK_DEVELOPER_TO_STRING() - SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkEmptyShader) - -protected: - SkEmptyShader(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {} - -private: - typedef SkShader INHERITED; -}; - -#endif diff --git a/libskia/include/core/SkEncodedImageFormat.h b/libskia/include/core/SkEncodedImageFormat.h new file mode 100644 index 00000000..8f792366 --- /dev/null +++ b/libskia/include/core/SkEncodedImageFormat.h @@ -0,0 +1,33 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkEncodedImageFormat_DEFINED +#define SkEncodedImageFormat_DEFINED + +#include + +/** + * Enum describing format of encoded data. + */ +enum class SkEncodedImageFormat { +#ifdef GOOGLE3 + kUnknown, +#endif + kBMP, + kGIF, + kICO, + kJPEG, + kPNG, + kWBMP, + kWEBP, + kPKM, + kKTX, + kASTC, + kDNG, +}; + +#endif // SkEncodedImageFormat_DEFINED diff --git a/libskia/include/core/SkError.h b/libskia/include/core/SkError.h deleted file mode 100644 index 678c9102..00000000 --- a/libskia/include/core/SkError.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2013 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef SkError_DEFINED -#define SkError_DEFINED - - -/** \file SkError.h -*/ - -enum SkError { - /** All is well - */ - kNoError_SkError=0, - - /** User argument passed to Skia function was invalid: NULL when that’s - * not allowed, out of numeric range, bad enum, or violating some - * other general precondition. - */ - kInvalidArgument_SkError, - - /** User tried to perform some operation in a state when the operation - * was not legal, or the operands make no sense (e.g., asking for - * pixels from an SkPictureCanvas). Other examples might be - * inset()’ing a rectangle to make it degenerate (negative width/height). - */ - kInvalidOperation_SkError, - - /** Probably not needed right now, but in the future we could have opaque - * handles for SkPictures floating around, and it would be a good idea - * to anticipate this kind of issue. - */ - kInvalidHandle_SkError, - - /** This is probably not possible because paint surely has defaults for - * everything, but perhaps a paint can get into a bad state somehow. - */ - kInvalidPaint_SkError, - - /** Skia was unable to allocate memory to perform some task. - */ - kOutOfMemory_SkError, - - /** Skia failed while trying to consume some external resource. - */ - kParseError_SkError, - - /** Something went wrong internally; could be resource exhaustion but - * will often be a bug. - */ - kInternalError_SkError -}; - -/** Return the current per-thread error code. Error codes are "sticky"; they - * are not not reset by subsequent successful operations. - */ -SkError SkGetLastError(); - -/** Clear the current per-thread error code back to kNoError_SkError. - */ -void SkClearLastError(); - -/** Type for callback functions to be invoked whenever an error is registered. - * Callback functions take the error code being set, as well as a context - * argument that is provided when the callback is registered. - */ -typedef void (*SkErrorCallbackFunction)(SkError, void *); - -/** Set the current per-thread error callback. - * - * @param cb The callback function to be invoked. Passing NULL - * for cb will revert to the default error callback which - * does nothing on release builds, but on debug builds will - * print an informative error message to the screen. - * @param context An arbitrary pointer that will be passed to - * the provided callback function. - */ -void SkSetErrorCallback(SkErrorCallbackFunction cb, void *context); - -/** Get a human-readable description of the last (per-thread) error that - * occurred. The returned error message will include not only a human - * readable version of the error code, but also information about the - * conditions that led to the error itself. - */ -const char *SkGetLastErrorString(); - -#endif /* SkError_DEFINED */ diff --git a/libskia/include/core/SkFilterQuality.h b/libskia/include/core/SkFilterQuality.h new file mode 100644 index 00000000..54fae51f --- /dev/null +++ b/libskia/include/core/SkFilterQuality.h @@ -0,0 +1,26 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkFilterQuality_DEFINED +#define SkFilterQuality_DEFINED + +#include "SkTypes.h" + +/** + * Controls how much filtering to be done when scaling/transforming complex colors + * e.g. images + */ +enum SkFilterQuality { + kNone_SkFilterQuality, //!< fastest but lowest quality, typically nearest-neighbor + kLow_SkFilterQuality, //!< typically bilerp + kMedium_SkFilterQuality, //!< typically bilerp + mipmaps for down-scaling + kHigh_SkFilterQuality, //!< slowest but highest quality, typically bicubic or better + + kLast_SkFilterQuality = kHigh_SkFilterQuality +}; + +#endif diff --git a/libskia/include/core/SkFlate.h b/libskia/include/core/SkFlate.h deleted file mode 100644 index e4c1417d..00000000 --- a/libskia/include/core/SkFlate.h +++ /dev/null @@ -1,52 +0,0 @@ - -/* - * Copyright 2010 The Android Open Source Project - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - - -#ifndef SkFlate_DEFINED -#define SkFlate_DEFINED - -#include "SkTypes.h" - -class SkData; -class SkWStream; -class SkStream; - -/** \class SkFlate - A class to provide access to the flate compression algorithm. -*/ -class SkFlate { -public: - /** Indicates if the flate algorithm is available. - */ - static bool HaveFlate(); - - /** - * Use the flate compression algorithm to compress the data in src, - * putting the result into dst. Returns false if an error occurs. - */ - static bool Deflate(SkStream* src, SkWStream* dst); - - /** - * Use the flate compression algorithm to compress the data in src, - * putting the result into dst. Returns false if an error occurs. - */ - static bool Deflate(const void* src, size_t len, SkWStream* dst); - - /** - * Use the flate compression algorithm to compress the data, - * putting the result into dst. Returns false if an error occurs. - */ - static bool Deflate(const SkData*, SkWStream* dst); - - /** Use the flate compression algorithm to decompress the data in src, - putting the result into dst. Returns false if an error occurs. - */ - static bool Inflate(SkStream* src, SkWStream* dst); -}; - -#endif diff --git a/libskia/include/core/SkFlattenable.h b/libskia/include/core/SkFlattenable.h index 5a6e2ae8..88aeb7ee 100644 --- a/libskia/include/core/SkFlattenable.h +++ b/libskia/include/core/SkFlattenable.h @@ -1,4 +1,3 @@ - /* * Copyright 2006 The Android Open Source Project * @@ -6,18 +5,34 @@ * found in the LICENSE file. */ - #ifndef SkFlattenable_DEFINED #define SkFlattenable_DEFINED #include "SkRefCnt.h" -class SkFlattenableReadBuffer; -class SkFlattenableWriteBuffer; +class SkReadBuffer; +class SkWriteBuffer; -#define SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(flattenable) \ - SkFlattenable::Registrar(#flattenable, flattenable::CreateProc, \ - flattenable::GetFlattenableType()); +class SkPrivateEffectInitializer; + +/* + * Flattening is straight-forward: + * 1. call getFactory() so we have a function-ptr to recreate the subclass + * 2. call flatten(buffer) to write out enough data for the factory to read + * + * Unflattening is easy for the caller: new_instance = factory(buffer) + * + * The complexity of supporting this is as follows. + * + * If your subclass wants to control unflattening, use this macro in your declaration: + * SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS + * This will provide a getFactory(), and require that the subclass implements CreateProc. + * + * For older buffers (before the DEEPFLATTENING change, the macros below declare + * a thin factory DeepCreateProc. It checks the version of the buffer, and if it is pre-deep, + * then it calls through to a (usually protected) constructor, passing the buffer. + * If the buffer is newer, then it directly calls the "real" factory: CreateProc. + */ #define SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP() static void InitializeFlattenables(); @@ -27,14 +42,16 @@ class SkFlattenableWriteBuffer; #define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END \ } -#define SK_DECLARE_UNFLATTENABLE_OBJECT() \ - virtual Factory getFactory() const SK_OVERRIDE { return NULL; } +#define SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(flattenable) \ + SkFlattenable::Register(#flattenable, flattenable::CreateProc, \ + flattenable::GetFlattenableType()); -#define SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(flattenable) \ - virtual Factory getFactory() const SK_OVERRIDE { return CreateProc; } \ - static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { \ - return SkNEW_ARGS(flattenable, (buffer)); \ - } +#define SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(flattenable) \ + private: \ + static sk_sp CreateProc(SkReadBuffer&); \ + friend class SkFlattenable::PrivateInitializer; \ + public: \ + Factory getFactory() const override { return CreateProc; } /** For SkFlattenable derived objects with a valid type This macro should only be used in base class objects in core @@ -54,6 +71,7 @@ class SK_API SkFlattenable : public SkRefCnt { public: enum Type { kSkColorFilter_Type, + kSkDrawable_Type, kSkDrawLooper_Type, kSkImageFilter_Type, kSkMaskFilter_Type, @@ -61,13 +79,12 @@ class SK_API SkFlattenable : public SkRefCnt { kSkPixelRef_Type, kSkRasterizer_Type, kSkShader_Type, - kSkUnitMapper_Type, + kSkUnused_Type, // used to be SkUnitMapper kSkXfermode_Type, + kSkNormalSource_Type, }; - SK_DECLARE_INST_COUNT(SkFlattenable) - - typedef SkFlattenable* (*Factory)(SkFlattenableReadBuffer&); + typedef sk_sp (*Factory)(SkReadBuffer&); SkFlattenable() {} @@ -77,9 +94,15 @@ class SK_API SkFlattenable : public SkRefCnt { */ virtual Factory getFactory() const = 0; - /** Returns the name of the object's class - */ - const char* getTypeName() const { return FactoryToName(getFactory()); } + /** + * Returns the name of the object's class. + * + * Subclasses should override this function if they intend to provide + * support for flattening without using the global registry. + * + * If the flattenable is registered, there is no need to override. + */ + virtual const char* getTypeName() const { return FactoryToName(getFactory()); } static Factory NameToFactory(const char name[]); static const char* FactoryToName(Factory); @@ -87,26 +110,23 @@ class SK_API SkFlattenable : public SkRefCnt { static void Register(const char name[], Factory, Type); - class Registrar { - public: - Registrar(const char name[], Factory factory, Type type) { - SkFlattenable::Register(name, factory, type); - } - }; + /** + * Override this if your subclass needs to record data that it will need to recreate itself + * from its CreateProc (returned by getFactory()). + */ + virtual void flatten(SkWriteBuffer&) const {} protected: - SkFlattenable(SkFlattenableReadBuffer&) {} - /** Override this to write data specific to your subclass into the buffer, - being sure to call your super-class' version first. This data will later - be passed to your Factory function, returned by getFactory(). - */ - virtual void flatten(SkFlattenableWriteBuffer&) const; + class PrivateInitializer { + public: + static void InitCore(); + static void InitEffects(); + }; private: static void InitializeFlattenablesIfNeeded(); friend class SkGraphics; - friend class SkFlattenableWriteBuffer; typedef SkRefCnt INHERITED; }; diff --git a/libskia/include/core/SkFlattenableBuffers.h b/libskia/include/core/SkFlattenableBuffers.h deleted file mode 100644 index aa61f21a..00000000 --- a/libskia/include/core/SkFlattenableBuffers.h +++ /dev/null @@ -1,260 +0,0 @@ - -/* - * Copyright 2012 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef SkFlattenableBuffers_DEFINED -#define SkFlattenableBuffers_DEFINED - -#include "SkColor.h" -#include "SkData.h" -#include "SkPaint.h" -#include "SkPoint.h" - -class SkBitmap; -class SkDrawLooper; -class SkFlattenable; -struct SkIRect; -class SkMatrix; -class SkOrderedReadBuffer; -class SkOrderedWriteBuffer; -class SkPath; -class SkPixelRef; -struct SkRect; -class SkRegion; -class SkStream; -class SkString; -class SkTypeface; -class SkUnitMapper; -class SkWStream; - -class SkFlattenableReadBuffer { -public: - SkFlattenableReadBuffer(); - virtual ~SkFlattenableReadBuffer(); - - bool isOrderedBinaryBuffer() { return NULL != getOrderedBinaryBuffer(); } - virtual SkOrderedReadBuffer* getOrderedBinaryBuffer() { return NULL; } - - enum Flags { - kCrossProcess_Flag = 1 << 0, - kScalarIsFloat_Flag = 1 << 1, - kPtrIs64Bit_Flag = 1 << 2, - /** The kValidation_Flag is used to force stream validations (by making - * sure that no operation reads past the end of the stream, for example) - * and error handling if any reading operation yields an invalid value. - */ - kValidation_Flag = 1 << 3, - }; - - void setFlags(uint32_t flags) { fFlags = flags; } - uint32_t getFlags() const { return fFlags; } - - bool isCrossProcess() const { return SkToBool(fFlags & (kCrossProcess_Flag | kValidation_Flag)); } - bool isScalarFloat() const { return SkToBool(fFlags & kScalarIsFloat_Flag); } - bool isPtr64Bit() const { return SkToBool(fFlags & kPtrIs64Bit_Flag); } - bool isValidating() const { return SkToBool(fFlags & kValidation_Flag); } - - // primitives - virtual bool readBool() = 0; - virtual SkColor readColor() = 0; - virtual SkFixed readFixed() = 0; - virtual int32_t readInt() = 0; - virtual SkScalar readScalar() = 0; - virtual uint32_t readUInt() = 0; - virtual int32_t read32() = 0; - - // strings -- the caller is responsible for freeing the string contents - virtual void readString(SkString* string) = 0; - virtual void* readEncodedString(size_t* length, SkPaint::TextEncoding encoding) = 0; - - /** - @param type This parameter is only used when using SkValidatingReadBuffer. It will verify - that the object about to be deserialized is of the given type or early return - NULL otherwise. The type provided here is the type of the base class of the - object to deserialize. - */ - virtual SkFlattenable* readFlattenable(SkFlattenable::Type type) = 0; - - SkColorFilter* readColorFilter(); - SkDrawLooper* readDrawLooper(); - SkImageFilter* readImageFilter(); - SkMaskFilter* readMaskFilter(); - SkPathEffect* readPathEffect(); - SkPixelRef* readPixelRef(); - SkRasterizer* readRasterizer(); - SkShader* readShader(); - SkUnitMapper* readUnitMapper(); - SkXfermode* readXfermode(); - - // common data structures - virtual void readPoint(SkPoint* point) = 0; - virtual void readMatrix(SkMatrix* matrix) = 0; - virtual void readIRect(SkIRect* rect) = 0; - virtual void readRect(SkRect* rect) = 0; - virtual void readRegion(SkRegion* region) = 0; - virtual void readPath(SkPath* path) = 0; - - // binary data and arrays - - /** - * In the following read.*Array(...) functions, the size parameter specifies the allocation - * size in number of elements (or in bytes, for void*) of the pointer parameter. If the - * pointer parameter's size does not match the size to be read, the pointer parameter's memory - * will then stay uninitialized, the cursor will be moved to the end of the stream and, in the - * case where isValidating() is true, an error flag will be set internally (see - * SkValidatingReadBuffer). - * If the sizes match, then "size" amount of memory will be read. - * - * @param size amount of memory expected to be read - * @return true if the size parameter matches the size to be read, false otherwise - */ - virtual bool readByteArray(void* value, size_t size) = 0; - virtual bool readColorArray(SkColor* colors, size_t size) = 0; - virtual bool readIntArray(int32_t* values, size_t size) = 0; - virtual bool readPointArray(SkPoint* points, size_t size) = 0; - virtual bool readScalarArray(SkScalar* values, size_t size) = 0; - - /** This helper peeks into the buffer and reports back the length of the next array in - * the buffer but does not change the state of the buffer. - */ - virtual uint32_t getArrayCount() = 0; - - // helper functions - virtual void* readFunctionPtr(); - virtual void readPaint(SkPaint* paint); - - virtual void readBitmap(SkBitmap* bitmap) = 0; - virtual SkTypeface* readTypeface() = 0; - - // helper function for classes with const SkPoint members - SkPoint readPoint() { - SkPoint point; - this->readPoint(&point); - return point; - } - - SkData* readByteArrayAsData() { - size_t len = this->getArrayCount(); - void* buffer = NULL; - if (this->validateAvailable(len)) { - buffer = sk_malloc_throw(len); - (void)this->readByteArray(buffer, len); - } else { - len = 0; - } - return SkData::NewFromMalloc(buffer, len); - } - - /** This function validates that the isValid input parameter is true - * If isValidating() is false, then true is always returned - * If isValidating() is true, then true is returned until validate() is called with isValid - * set to false. When isValid is false, an error flag will be set internally and, from that - * point on, validate() will return false. The error flag cannot be unset. - * - * @param isValid result of a test that is expected to be true - */ - virtual bool validate(bool isValid); - - /** This function returns true by default - * If isValidating() is true, it will return false if the internal error flag is set. - * Otherwise, it will return true. - */ - virtual bool isValid() const { return true; } - - /** This function returns true by default - * If isValidating() is true, it will return whether there's - * at least "size" memory left to read in the stream. - * - * @param size amount of memory that should still be available - */ - virtual bool validateAvailable(size_t size) { return true; } - -private: - template T* readFlattenableT(); - uint32_t fFlags; -}; - -/////////////////////////////////////////////////////////////////////////////// - -class SkFlattenableWriteBuffer { -public: - SkFlattenableWriteBuffer(); - virtual ~SkFlattenableWriteBuffer(); - - virtual bool isOrderedBinaryBuffer() { return false; } - virtual SkOrderedWriteBuffer* getOrderedBinaryBuffer() { sk_throw(); return NULL; } - - // primitives - virtual void writeByteArray(const void* data, size_t size) = 0; - virtual void writeBool(bool value) = 0; - virtual void writeFixed(SkFixed value) = 0; - virtual void writeScalar(SkScalar value) = 0; - virtual void writeScalarArray(const SkScalar* value, uint32_t count) = 0; - virtual void writeInt(int32_t value) = 0; - virtual void writeIntArray(const int32_t* value, uint32_t count) = 0; - virtual void writeUInt(uint32_t value) = 0; - virtual void write32(int32_t value) = 0; // printf in hex - virtual void writeString(const char* value) = 0; - virtual void writeEncodedString(const void* value, size_t byteLength, - SkPaint::TextEncoding encoding) = 0; - - // common data structures - virtual void writeFlattenable(const SkFlattenable* flattenable) = 0; - virtual void writeColor(const SkColor& color) = 0; - virtual void writeColorArray(const SkColor* color, uint32_t count) = 0; - virtual void writePoint(const SkPoint& point) = 0; - virtual void writePointArray(const SkPoint* points, uint32_t count) = 0; - virtual void writeMatrix(const SkMatrix& matrix) = 0; - virtual void writeIRect(const SkIRect& rect) = 0; - virtual void writeRect(const SkRect& rect) = 0; - virtual void writeRegion(const SkRegion& region) = 0; - virtual void writePath(const SkPath& path) = 0; - virtual size_t writeStream(SkStream* stream, size_t length) = 0; - - // helper functions - virtual void writeFunctionPtr(void* ptr); - virtual void writePaint(const SkPaint& paint); - - virtual void writeBitmap(const SkBitmap& bitmap) = 0; - virtual void writeTypeface(SkTypeface* typeface) = 0; - - virtual bool writeToStream(SkWStream*) = 0; - - enum Flags { - kCrossProcess_Flag = 0x01, - /** The kValidation_Flag is used here to make sure the write operation - * is symmetric with the read operation using the equivalent flag - * SkFlattenableReadBuffer::kValidation_Flag. - */ - kValidation_Flag = 0x02, - }; - - uint32_t getFlags() const { return fFlags; } - void setFlags(uint32_t flags) { fFlags = flags; } - - bool isCrossProcess() const { - return SkToBool(fFlags & (kCrossProcess_Flag | kValidation_Flag)); - } - - bool isValidating() const { - return SkToBool(fFlags & kValidation_Flag); - } - - bool persistTypeface() const { return (fFlags & kCrossProcess_Flag) != 0; } - - void writeDataAsByteArray(SkData* data) { - this->writeByteArray(data->data(), data->size()); - } - -protected: - // A helper function so that each subclass does not have to be a friend of SkFlattenable - void flattenObject(const SkFlattenable* obj, SkFlattenableWriteBuffer& buffer); - - uint32_t fFlags; -}; - -#endif diff --git a/libskia/include/core/SkFlattenableSerialization.h b/libskia/include/core/SkFlattenableSerialization.h index ffb1b5ae..c6fd53db 100644 --- a/libskia/include/core/SkFlattenableSerialization.h +++ b/libskia/include/core/SkFlattenableSerialization.h @@ -11,9 +11,12 @@ #include "SkFlattenable.h" class SkData; +class SkImageFilter; SK_API SkData* SkValidatingSerializeFlattenable(SkFlattenable*); SK_API SkFlattenable* SkValidatingDeserializeFlattenable(const void* data, size_t size, SkFlattenable::Type type); +SK_API sk_sp SkValidatingDeserializeImageFilter(const void* data, size_t size); + #endif diff --git a/libskia/include/core/SkFloatingPoint.h b/libskia/include/core/SkFloatingPoint.h deleted file mode 100644 index 7dfa9d86..00000000 --- a/libskia/include/core/SkFloatingPoint.h +++ /dev/null @@ -1,140 +0,0 @@ - -/* - * Copyright 2006 The Android Open Source Project - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - - -#ifndef SkFloatingPoint_DEFINED -#define SkFloatingPoint_DEFINED - -#include "SkTypes.h" - -#include -#include -#include "SkFloatBits.h" - -// C++98 cmath std::pow seems to be the earliest portable way to get float pow. -// However, on Linux including cmath undefines isfinite. -// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=14608 -static inline float sk_float_pow(float base, float exp) { - return powf(base, exp); -} - -static inline float sk_float_copysign(float x, float y) { - int32_t xbits = SkFloat2Bits(x); - int32_t ybits = SkFloat2Bits(y); - return SkBits2Float((xbits & 0x7FFFFFFF) | (ybits & 0x80000000)); -} - -#ifdef SK_BUILD_FOR_WINCE - #define sk_float_sqrt(x) (float)::sqrt(x) - #define sk_float_sin(x) (float)::sin(x) - #define sk_float_cos(x) (float)::cos(x) - #define sk_float_tan(x) (float)::tan(x) - #define sk_float_acos(x) (float)::acos(x) - #define sk_float_asin(x) (float)::asin(x) - #define sk_float_atan2(y,x) (float)::atan2(y,x) - #define sk_float_abs(x) (float)::fabs(x) - #define sk_float_mod(x,y) (float)::fmod(x,y) - #define sk_float_exp(x) (float)::exp(x) - #define sk_float_log(x) (float)::log(x) - #define sk_float_floor(x) (float)::floor(x) - #define sk_float_ceil(x) (float)::ceil(x) -#else - #define sk_float_sqrt(x) sqrtf(x) - #define sk_float_sin(x) sinf(x) - #define sk_float_cos(x) cosf(x) - #define sk_float_tan(x) tanf(x) - #define sk_float_floor(x) floorf(x) - #define sk_float_ceil(x) ceilf(x) -#ifdef SK_BUILD_FOR_MAC - #define sk_float_acos(x) static_cast(acos(x)) - #define sk_float_asin(x) static_cast(asin(x)) -#else - #define sk_float_acos(x) acosf(x) - #define sk_float_asin(x) asinf(x) -#endif - #define sk_float_atan2(y,x) atan2f(y,x) - #define sk_float_abs(x) fabsf(x) - #define sk_float_mod(x,y) fmodf(x,y) - #define sk_float_exp(x) expf(x) - #define sk_float_log(x) logf(x) -#endif - -#ifdef SK_BUILD_FOR_WIN - #define sk_float_isfinite(x) _finite(x) - #define sk_float_isnan(x) _isnan(x) - static inline int sk_float_isinf(float x) { - int32_t bits = SkFloat2Bits(x); - return (bits << 1) == (0xFF << 24); - } -#else - #define sk_float_isfinite(x) isfinite(x) - #define sk_float_isnan(x) isnan(x) - #define sk_float_isinf(x) isinf(x) -#endif - -#define sk_double_isnan(a) sk_float_isnan(a) - -#ifdef SK_USE_FLOATBITS - #define sk_float_floor2int(x) SkFloatToIntFloor(x) - #define sk_float_round2int(x) SkFloatToIntRound(x) - #define sk_float_ceil2int(x) SkFloatToIntCeil(x) -#else - #define sk_float_floor2int(x) (int)sk_float_floor(x) - #define sk_float_round2int(x) (int)sk_float_floor((x) + 0.5f) - #define sk_float_ceil2int(x) (int)sk_float_ceil(x) -#endif - -extern const uint32_t gIEEENotANumber; -extern const uint32_t gIEEEInfinity; -extern const uint32_t gIEEENegativeInfinity; - -#define SK_FloatNaN (*SkTCast(&gIEEENotANumber)) -#define SK_FloatInfinity (*SkTCast(&gIEEEInfinity)) -#define SK_FloatNegativeInfinity (*SkTCast(&gIEEENegativeInfinity)) - -#if defined(__SSE__) -#include -#elif defined(__ARM_NEON__) -#include -#endif - -// Fast, approximate inverse square root. -// Compare to name-brand "1.0f / sk_float_sqrt(x)". Should be around 10x faster on SSE, 2x on NEON. -static inline float sk_float_rsqrt(const float x) { -// We want all this inlined, so we'll inline SIMD and just take the hit when we don't know we've got -// it at compile time. This is going to be too fast to productively hide behind a function pointer. -// -// We do one step of Newton's method to refine the estimates in the NEON and null paths. No -// refinement is faster, but very innacurate. Two steps is more accurate, but slower than 1/sqrt. -#if defined(__SSE__) - float result; - _mm_store_ss(&result, _mm_rsqrt_ss(_mm_set_ss(x))); - return result; -#elif defined(__ARM_NEON__) - // Get initial estimate. - const float32x2_t xx = vdup_n_f32(x); // Clever readers will note we're doing everything 2x. - float32x2_t estimate = vrsqrte_f32(xx); - - // One step of Newton's method to refine. - const float32x2_t estimate_sq = vmul_f32(estimate, estimate); - estimate = vmul_f32(estimate, vrsqrts_f32(xx, estimate_sq)); - return vget_lane_f32(estimate, 0); // 1 will work fine too; the answer's in both places. -#else - // Get initial estimate. - int i = *SkTCast(&x); - i = 0x5f3759df - (i>>1); - float estimate = *SkTCast(&i); - - // One step of Newton's method to refine. - const float estimate_sq = estimate*estimate; - estimate *= (1.5f-0.5f*x*estimate_sq); - return estimate; -#endif -} - -#endif diff --git a/libskia/include/core/SkFont.h b/libskia/include/core/SkFont.h new file mode 100644 index 00000000..e50909aa --- /dev/null +++ b/libskia/include/core/SkFont.h @@ -0,0 +1,176 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkFont_DEFINED +#define SkFont_DEFINED + +#include "SkRefCnt.h" +#include "SkScalar.h" + +class SkPaint; +class SkTypeface; + +enum SkTextEncoding { + kUTF8_SkTextEncoding, + kUTF16_SkTextEncoding, + kUTF32_SkTextEncoding, + kGlyphID_SkTextEncoding, +}; + +/* + 1. The Hinting enum in SkPaint is gone entirely, absorbed into SkFont's flags. + + 2. SkPaint Flags look like this today + + enum Flags { + kAntiAlias_Flag = 0x01, //!< mask to enable antialiasing + kDither_Flag = 0x04, //!< mask to enable dithering + kUnderlineText_Flag = 0x08, //!< mask to enable underline text + kStrikeThruText_Flag = 0x10, //!< mask to enable strike-thru text + kFakeBoldText_Flag = 0x20, //!< mask to enable fake-bold text + kLinearText_Flag = 0x40, //!< mask to enable linear-text + kSubpixelText_Flag = 0x80, //!< mask to enable subpixel text positioning + kDevKernText_Flag = 0x100, //!< mask to enable device kerning text + kLCDRenderText_Flag = 0x200, //!< mask to enable subpixel glyph renderering + kEmbeddedBitmapText_Flag = 0x400, //!< mask to enable embedded bitmap strikes + kAutoHinting_Flag = 0x800, //!< mask to force Freetype's autohinter + kVerticalText_Flag = 0x1000, + kGenA8FromLCD_Flag = 0x2000, // hack for GDI -- do not use if you can help it + }; + + SkFont would absorb these: + + kFakeBoldText_Flag = 0x20, //!< mask to enable fake-bold text + kLinearText_Flag = 0x40, //!< mask to enable linear-text + kSubpixelText_Flag = 0x80, //!< mask to enable subpixel text positioning + kDevKernText_Flag = 0x100, //!< mask to enable device kerning text + kLCDRenderText_Flag = 0x200, //!< mask to enable subpixel glyph renderering + kEmbeddedBitmapText_Flag = 0x400, //!< mask to enable embedded bitmap strikes + kAutoHinting_Flag = 0x800, //!< mask to force Freetype's autohinter + kVerticalText_Flag = 0x1000, + kGenA8FromLCD_Flag = 0x2000, // hack for GDI -- do not use if you can help it + + leaving these still in paint + + kAntiAlias_Flag = 0x01, //!< mask to enable antialiasing + kDither_Flag = 0x04, //!< mask to enable dithering + kUnderlineText_Flag = 0x08, //!< mask to enable underline text + kStrikeThruText_Flag = 0x10, //!< mask to enable strike-thru text + + 3. Antialiasing + + SkFont has a mask-type: BW, AA, LCD + SkPaint has antialias boolean + + What to do if the font's mask-type disagrees with the paint? + + */ + +class SkFont : public SkRefCnt { +public: + enum Flags { + /** + * Use the system's automatic hinting mechanism to hint the typeface. + * This is a last resort hinting method applied only if other hinting methods do not apply. + * TODO: where to put auto-normal vs auto-light? + */ + kEnableAutoHints_Flag = 1 << 0, + + /** + * If the typeface contains explicit bytecodes for hinting, use them. + * If both bytecode and auto hints are specified, attempt to use the bytecodes first; + * if that fails (e.g. there are no codes), then attempt to autohint. + */ + kEnableByteCodeHints_Flag = 1 << 1, + + /** + * If the typeface contains explicit bitmaps for hinting, use them. + * If both bytecode and auto hints are also specified, attempt to use the bitmaps first; + * if that fails (e.g. there are no bitmaps), then attempt to bytecode or autohint. + */ + kEmbeddedBitmaps_Flag = 1 << 2, + + /** + * Use rounded metric values (e.g. advance). + * If either auto or bytecode hinting was used, apply those results to the metrics of the + * glyphs as well. If no hinting was applied, the metrics will just be rounded to the + * nearest integer. + * + * This applies to calls that return metrics (e.g. measureText) and to drawing the glyphs + * (see SkCanvas drawText and drawPosText). + */ + kUseNonlinearMetrics_Flag = 1 << 3, + + kVertical_Flag = 1 << 4, + kGenA8FromLCD_Flag = 1 << 5, + kEmbolden_Flag = 1 << 6, + kDevKern_Flag = 1 << 7, // ifdef ANDROID ? + }; + + enum MaskType { + kBW_MaskType, + kA8_MaskType, + kLCD_MaskType, + }; + + static sk_sp Make(sk_sp, SkScalar size, MaskType, uint32_t flags); + static sk_sp Make(sk_sp, SkScalar size, SkScalar scaleX, SkScalar skewX, + MaskType, uint32_t flags); + + /** + * Return a font with the same attributes of this font, but with the specified size. + * If size is not supported (e.g. <= 0 or non-finite) NULL will be returned. + */ + sk_sp makeWithSize(SkScalar size) const; + /** + * Return a font with the same attributes of this font, but with the flags. + */ + sk_sp makeWithFlags(uint32_t newFlags) const; + + SkTypeface* getTypeface() const { return fTypeface.get(); } + SkScalar getSize() const { return fSize; } + SkScalar getScaleX() const { return fScaleX; } + SkScalar getSkewX() const { return fSkewX; } + uint32_t getFlags() const { return fFlags; } + MaskType getMaskType() const { return (MaskType)fMaskType; } + + bool isVertical() const { return SkToBool(fFlags & kVertical_Flag); } + bool isEmbolden() const { return SkToBool(fFlags & kEmbolden_Flag); } + bool isEnableAutoHints() const { return SkToBool(fFlags & kEnableAutoHints_Flag); } + bool isEnableByteCodeHints() const { return SkToBool(fFlags & kEnableByteCodeHints_Flag); } + bool isUseNonLinearMetrics() const { return SkToBool(fFlags & kUseNonlinearMetrics_Flag); } + bool isDevKern() const { return SkToBool(fFlags & kDevKern_Flag); } + + int textToGlyphs(const void* text, size_t byteLength, SkTextEncoding, + SkGlyphID glyphs[], int maxGlyphCount) const; + + int countText(const void* text, size_t byteLength, SkTextEncoding encoding) { + return this->textToGlyphs(text, byteLength, encoding, nullptr, 0); + } + + SkScalar measureText(const void* text, size_t byteLength, SkTextEncoding) const; + + static sk_sp Testing_CreateFromPaint(const SkPaint&); + +private: + enum { + kAllFlags = 0xFF, + }; + + SkFont(sk_sp, SkScalar size, SkScalar scaleX, SkScalar skewX, MaskType, + uint32_t flags); + + sk_sp fTypeface; + SkScalar fSize; + SkScalar fScaleX; + SkScalar fSkewX; + uint16_t fFlags; + uint8_t fMaskType; +// uint8_t fPad; +}; + +#endif diff --git a/libskia/include/core/SkFontHost.h b/libskia/include/core/SkFontHost.h deleted file mode 100644 index 4c5013fe..00000000 --- a/libskia/include/core/SkFontHost.h +++ /dev/null @@ -1,131 +0,0 @@ - -/* - * Copyright 2006 The Android Open Source Project - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - - -#ifndef SkFontHost_DEFINED -#define SkFontHost_DEFINED - -#include "SkTypeface.h" - -class SkDescriptor; -class SkScalerContext; -struct SkScalerContextRec; -class SkStream; -class SkWStream; - -/** \class SkFontHost - - This class is ported to each environment. It is responsible for bridging - the gap between the (sort of) abstract class SkTypeface and the - platform-specific implementation that provides access to font files. - - One basic task is for each create (subclass of) SkTypeface, the FontHost is - responsible for assigning a uniqueID. The ID should be unique for the - underlying font file/data, not unique per typeface instance. Thus it is - possible/common to request a typeface for the same font more than once - (e.g. asking for the same font by name several times). The FontHost may - return seperate typeface instances in that case, or it may choose to use a - cache and return the same instance (but calling typeface->ref(), since the - caller is always responsible for calling unref() on each instance that is - returned). Either way, the fontID for those instance(s) will be the same. - In addition, the fontID should never be set to 0. That value is used as a - sentinel to indicate no-font-id. - - The major aspects are: - 1) Given either a name/style, return a subclass of SkTypeface that - references the closest matching font available on the host system. - 2) Given the data for a font (either in a stream or a file name), return - a typeface that allows access to that data. - 3) Each typeface instance carries a 32bit ID for its corresponding font. - SkFontHost turns that ID into a stream to access the font's data. - 4) Given a font ID, return a subclass of SkScalerContext, which connects a - font scaler (e.g. freetype or other) to the font's data. - 5) Utilites to manage the font cache (budgeting) and gamma correction -*/ -class SK_API SkFontHost { -public: - /** LCDs either have their color elements arranged horizontally or - vertically. When rendering subpixel glyphs we need to know which way - round they are. - - Note, if you change this after startup, you'll need to flush the glyph - cache because it'll have the wrong type of masks cached. - - @deprecated use SkPixelGeometry instead. - */ - enum LCDOrientation { - kHorizontal_LCDOrientation = 0, //!< this is the default - kVertical_LCDOrientation = 1 - }; - - /** @deprecated set on Device creation. */ - static void SetSubpixelOrientation(LCDOrientation orientation); - /** @deprecated get from Device. */ - static LCDOrientation GetSubpixelOrientation(); - - /** LCD color elements can vary in order. For subpixel text we need to know - the order which the LCDs uses so that the color fringes are in the - correct place. - - Note, if you change this after startup, you'll need to flush the glyph - cache because it'll have the wrong type of masks cached. - - kNONE_LCDOrder means that the subpixel elements are not spatially - separated in any usable fashion. - - @deprecated use SkPixelGeometry instead. - */ - enum LCDOrder { - kRGB_LCDOrder = 0, //!< this is the default - kBGR_LCDOrder = 1, - kNONE_LCDOrder = 2 - }; - - /** @deprecated set on Device creation. */ - static void SetSubpixelOrder(LCDOrder order); - /** @deprecated get from Device. */ - static LCDOrder GetSubpixelOrder(); - -private: - /** Return a new, closest matching typeface given either an existing family - (specified by a typeface in that family) or by a familyName and a - requested style. - 1) If familyFace is null, use familyName. - 2) If familyName is null, use data (UTF-16 to cover). - 3) If all are null, return the default font that best matches style - */ - static SkTypeface* CreateTypeface(const SkTypeface* familyFace, - const char familyName[], - SkTypeface::Style style); - - /** Return a new typeface given the data buffer. If the data does not - represent a valid font, returns null. - - If a typeface instance is returned, the caller is responsible for - calling unref() on the typeface when they are finished with it. - - The returned typeface may or may not have called ref() on the stream - parameter. If the typeface has not called ref(), then it may have made - a copy of the releveant data. In either case, the caller is still - responsible for its refcnt ownership of the stream. - */ - static SkTypeface* CreateTypefaceFromStream(SkStream*); - - /** Return a new typeface from the specified file path. If the file does not - represent a valid font, this returns null. If a typeface is returned, - the caller is responsible for calling unref() when it is no longer used. - */ - static SkTypeface* CreateTypefaceFromFile(const char path[]); - - /////////////////////////////////////////////////////////////////////////// - - friend class SkScalerContext; - friend class SkTypeface; -}; - -#endif diff --git a/libskia/include/core/SkFontLCDConfig.h b/libskia/include/core/SkFontLCDConfig.h index 03ee09f8..58b5a82b 100644 --- a/libskia/include/core/SkFontLCDConfig.h +++ b/libskia/include/core/SkFontLCDConfig.h @@ -10,7 +10,7 @@ #include "SkTypes.h" -class SkFontLCDConfig { +class SK_API SkFontLCDConfig { public: /** LCDs either have their color elements arranged horizontally or vertically. When rendering subpixel glyphs we need to know which way diff --git a/libskia/include/ports/SkFontStyle.h b/libskia/include/core/SkFontStyle.h similarity index 70% rename from libskia/include/ports/SkFontStyle.h rename to libskia/include/core/SkFontStyle.h index 9d9a912d..7dd25910 100644 --- a/libskia/include/ports/SkFontStyle.h +++ b/libskia/include/core/SkFontStyle.h @@ -13,15 +13,17 @@ class SK_API SkFontStyle { public: enum Weight { - kThin_Weight = 100, - kExtraLight_Weight = 200, - kLight_Weight = 300, - kNormal_Weight = 400, - kMedium_Weight = 500, - kSemiBold_Weight = 600, - kBold_Weight = 700, - kExtraBold_Weight = 800, - kBlack_Weight = 900 + kInvisible_Weight = 0, + kThin_Weight = 100, + kExtraLight_Weight = 200, + kLight_Weight = 300, + kNormal_Weight = 400, + kMedium_Weight = 500, + kSemiBold_Weight = 600, + kBold_Weight = 700, + kExtraBold_Weight = 800, + kBlack_Weight = 900, + kExtraBlack_Weight = 1000, }; enum Width { @@ -33,17 +35,20 @@ class SK_API SkFontStyle { kSemiExpanded_Width = 6, kExpanded_Width = 7, kExtraExpanded_Width = 8, - kUltaExpanded_Width = 9 + kUltraExpanded_Width = 9, }; enum Slant { kUpright_Slant, kItalic_Slant, + kOblique_Slant, }; SkFontStyle(); SkFontStyle(int weight, int width, Slant); + static SkFontStyle FromOldStyle(unsigned oldStyle); + bool operator==(const SkFontStyle& rhs) const { return fUnion.fU32 == rhs.fUnion.fU32; } @@ -52,10 +57,6 @@ class SK_API SkFontStyle { int width() const { return fUnion.fR.fWidth; } Slant slant() const { return (Slant)fUnion.fR.fSlant; } - bool isItalic() const { - return kItalic_Slant == fUnion.fR.fSlant; - } - private: union { struct { diff --git a/libskia/include/core/SkGraphics.h b/libskia/include/core/SkGraphics.h index 2667a388..d5a730d9 100644 --- a/libskia/include/core/SkGraphics.h +++ b/libskia/include/core/SkGraphics.h @@ -1,4 +1,3 @@ - /* * Copyright 2006 The Android Open Source Project * @@ -6,25 +5,26 @@ * found in the LICENSE file. */ - #ifndef SkGraphics_DEFINED #define SkGraphics_DEFINED #include "SkTypes.h" +class SkData; +class SkImageGenerator; +class SkTraceMemoryDump; + class SK_API SkGraphics { public: /** * Call this at process initialization time if your environment does not - * permit static global initializers that execute code. Note that - * Init() is not thread-safe. + * permit static global initializers that execute code. + * Init() is thread-safe and idempotent. */ static void Init(); - /** - * Call this to release any memory held privately, such as the font cache. - */ - static void Term(); + // We're in the middle of cleaning this up. + static void Term() {} /** * Return the version numbers for the library. If the parameter is not @@ -79,9 +79,53 @@ class SK_API SkGraphics { */ static void PurgeFontCache(); - static size_t GetImageCacheBytesUsed(); - static size_t GetImageCacheByteLimit(); - static size_t SetImageCacheByteLimit(size_t newLimit); + /** + * Scaling bitmaps with the kHigh_SkFilterQuality setting is + * expensive, so the result is saved in the global Scaled Image + * Cache. + * + * This function returns the memory usage of the Scaled Image Cache. + */ + static size_t GetResourceCacheTotalBytesUsed(); + + /** + * These functions get/set the memory usage limit for the resource cache, used for temporary + * bitmaps and other resources. Entries are purged from the cache when the memory useage + * exceeds this limit. + */ + static size_t GetResourceCacheTotalByteLimit(); + static size_t SetResourceCacheTotalByteLimit(size_t newLimit); + + /** + * For debugging purposes, this will attempt to purge the resource cache. It + * does not change the limit. + */ + static void PurgeResourceCache(); + + /** + * When the cachable entry is very lage (e.g. a large scaled bitmap), adding it to the cache + * can cause most/all of the existing entries to be purged. To avoid the, the client can set + * a limit for a single allocation. If a cacheable entry would have been cached, but its size + * exceeds this limit, then we do not attempt to cache it at all. + * + * Zero is the default value, meaning we always attempt to cache entries. + */ + static size_t GetResourceCacheSingleAllocationByteLimit(); + static size_t SetResourceCacheSingleAllocationByteLimit(size_t newLimit); + + /** + * Dumps memory usage of caches using the SkTraceMemoryDump interface. See SkTraceMemoryDump + * for usage of this method. + */ + static void DumpMemoryStatistics(SkTraceMemoryDump* dump); + + /** + * Free as much globally cached memory as possible. This will purge all private caches in Skia, + * including font and image caches. + * + * If there are caches associated with GPU context, those will not be affected by this call. + */ + static void PurgeAllCaches(); /** * Applications with command line options may pass optional state, such @@ -113,12 +157,17 @@ class SK_API SkGraphics { */ static void SetTLSFontCacheLimit(size_t bytes); -private: - /** This is automatically called by SkGraphics::Init(), and must be - implemented by the host OS. This allows the host OS to register a callback - with the C++ runtime to call SkGraphics::FreeCaches() - */ - static void InstallNewHandler(); + typedef SkImageGenerator* (*ImageGeneratorFromEncodedFactory)(SkData*); + + /** + * To instantiate images from encoded data, first looks at this runtime function-ptr. If it + * exists, it is called to create an SkImageGenerator from SkData. If there is no function-ptr + * or there is, but it returns NULL, then skia will call its internal default implementation. + * + * Returns the previous factory (which could be NULL). + */ + static ImageGeneratorFromEncodedFactory + SetImageGeneratorFromEncodedFactory(ImageGeneratorFromEncodedFactory); }; class SkAutoGraphics { @@ -126,9 +175,6 @@ class SkAutoGraphics { SkAutoGraphics() { SkGraphics::Init(); } - ~SkAutoGraphics() { - SkGraphics::Term(); - } }; #endif diff --git a/libskia/include/core/SkImage.h b/libskia/include/core/SkImage.h index 0bff589f..625d0a0b 100644 --- a/libskia/include/core/SkImage.h +++ b/libskia/include/core/SkImage.h @@ -8,21 +8,26 @@ #ifndef SkImage_DEFINED #define SkImage_DEFINED +#include "SkFilterQuality.h" #include "SkImageInfo.h" #include "SkImageEncoder.h" #include "SkRefCnt.h" #include "SkScalar.h" +#include "SkShader.h" class SkData; class SkCanvas; +class SkColorTable; +class SkImageGenerator; class SkPaint; -class SkShader; +class SkPicture; +class SkPixelSerializer; +class SkString; +class SkSurface; class GrContext; +class GrContextThreadSafeProxy; class GrTexture; -// need for TileMode -#include "SkShader.h" - /** * SkImage is an abstraction for drawing a rectagle of pixels, though the * particular type of image could be actually storing its data on the GPU, or @@ -32,69 +37,233 @@ class GrTexture; * The content of SkImage is always immutable, though the actual storage may * change, if for example that image can be re-created via encoded data or * other means. + * + * SkImage always has a non-zero dimensions. If there is a request to create a new image, either + * directly or via SkSurface, and either of the requested dimensions are zero, then NULL will be + * returned. */ class SK_API SkImage : public SkRefCnt { public: - SK_DECLARE_INST_COUNT(SkImage) - -#ifdef SK_SUPPORT_LEGACY_COLORTYPE - typedef SkColorType ColorType; - - static const SkColorType kAlpha_8_ColorType = kAlpha_8_SkColorType; - static const SkColorType kARGB_4444_ColorType = kARGB_4444_SkColorType; - static const SkColorType kRGB_565_ColorType = kRGB_565_SkColorType; - static const SkColorType kRGBA_8888_ColorType = kRGBA_8888_SkColorType; - static const SkColorType kBGRA_8888_ColorType = kBGRA_8888_SkColorType; - static const SkColorType kPMColor_ColorType = kPMColor_SkColorType; - static const SkColorType kLastEnum_ColorType = kLastEnum_SkColorType; -#endif + typedef SkImageInfo Info; + typedef void* ReleaseContext; -#ifdef SK_SUPPORT_LEGACY_ALPHATYPE - typedef SkAlphaType AlphaType; + static sk_sp MakeRasterCopy(const SkPixmap&); + static sk_sp MakeRasterData(const Info&, sk_sp pixels, size_t rowBytes); - static const SkAlphaType kIgnore_AlphaType = kIgnore_SkAlphaType; - static const SkAlphaType kOpaque_AlphaType = kOpaque_SkAlphaType; - static const SkAlphaType kPremul_AlphaType = kPremul_SkAlphaType; - static const SkAlphaType kUnpremul_AlphaType = kUnpremul_SkAlphaType; -#endif + typedef void (*RasterReleaseProc)(const void* pixels, ReleaseContext); - typedef SkImageInfo Info; + /** + * Return a new Image referencing the specified pixels. These must remain valid and unchanged + * until the specified release-proc is called, indicating that Skia no longer has a reference + * to the pixels. + * + * Returns NULL if the requested pixmap info is unsupported. + */ + static sk_sp MakeFromRaster(const SkPixmap&, RasterReleaseProc, ReleaseContext); - static SkImage* NewRasterCopy(const Info&, const void* pixels, size_t rowBytes); - static SkImage* NewRasterData(const Info&, SkData* pixels, size_t rowBytes); - static SkImage* NewEncodedData(SkData*); + /** + * Construct a new image from the specified bitmap. If the bitmap is marked immutable, and + * its pixel memory is shareable, it may be shared instead of copied. + */ + static sk_sp MakeFromBitmap(const SkBitmap&); + + /** + * Construct a new SkImage based on the given ImageGenerator. Returns NULL on error. + * This function will always take ownership of the passed generator. + * + * If a subset is specified, it must be contained within the generator's bounds. + */ + static sk_sp MakeFromGenerator(SkImageGenerator*, const SkIRect* subset = nullptr); /** - * GrTexture is a more logical parameter for this factory, but its - * interactions with scratch cache still has issues, so for now we take - * SkBitmap instead. This will be changed in the future. skbug.com/1449 + * Construct a new SkImage based on the specified encoded data. Returns NULL on failure, + * which can mean that the format of the encoded data was not recognized/supported. + * + * If a subset is specified, it must be contained within the encoded data's bounds. */ - static SkImage* NewTexture(const SkBitmap&); + static sk_sp MakeFromEncoded(sk_sp encoded, const SkIRect* subset = nullptr); + + /** + * Create a new image from the specified descriptor. Note - the caller is responsible for + * managing the lifetime of the underlying platform texture. + * + * Will return NULL if the specified descriptor is unsupported. + */ + static sk_sp MakeFromTexture(GrContext* ctx, const GrBackendTextureDesc& desc) { + return MakeFromTexture(ctx, desc, kPremul_SkAlphaType, nullptr, nullptr, nullptr); + } + + static sk_sp MakeFromTexture(GrContext* ctx, const GrBackendTextureDesc& de, + SkAlphaType at) { + return MakeFromTexture(ctx, de, at, nullptr, nullptr, nullptr); + } + + typedef void (*TextureReleaseProc)(ReleaseContext); + + /** + * Create a new image from the specified descriptor. The underlying platform texture must stay + * valid and unaltered until the specified release-proc is invoked, indicating that Skia + * no longer is holding a reference to it. + * + * Will return NULL if the specified descriptor is unsupported. + */ + static sk_sp MakeFromTexture(GrContext* ctx, const GrBackendTextureDesc& desc, + SkAlphaType at, TextureReleaseProc trp, + ReleaseContext rc) { + return MakeFromTexture(ctx, desc, at, nullptr, trp, rc); + } + + /** + * Create a new image from the specified descriptor. The underlying platform texture must stay + * valid and unaltered until the specified release-proc is invoked, indicating that Skia + * no longer is holding a reference to it. + * + * Will return NULL if the specified descriptor is unsupported. + */ + static sk_sp MakeFromTexture(GrContext*, const GrBackendTextureDesc&, SkAlphaType, + sk_sp, TextureReleaseProc, ReleaseContext); + + /** + * Create a new image from the specified descriptor. Note - Skia will delete or recycle the + * texture when the image is released. + * + * Will return NULL if the specified descriptor is unsupported. + */ + static sk_sp MakeFromAdoptedTexture(GrContext*, const GrBackendTextureDesc&, + SkAlphaType = kPremul_SkAlphaType, + sk_sp = nullptr); + + /** + * Create a new image by copying the pixels from the specified y, u, v textures. The data + * from the textures is immediately ingested into the image and the textures can be modified or + * deleted after the function returns. The image will have the dimensions of the y texture. + */ + static sk_sp MakeFromYUVTexturesCopy(GrContext*, SkYUVColorSpace, + const GrBackendObject yuvTextureHandles[3], + const SkISize yuvSizes[3], + GrSurfaceOrigin, + sk_sp = nullptr); + + /** + * Create a new image by copying the pixels from the specified y and uv textures. The data + * from the textures is immediately ingested into the image and the textures can be modified or + * deleted after the function returns. The image will have the dimensions of the y texture. + */ + static sk_sp MakeFromNV12TexturesCopy(GrContext*, SkYUVColorSpace, + const GrBackendObject nv12TextureHandles[2], + const SkISize nv12Sizes[2], GrSurfaceOrigin, + sk_sp = nullptr); + + static sk_sp MakeFromPicture(sk_sp, const SkISize& dimensions, + const SkMatrix*, const SkPaint*); + + static sk_sp MakeTextureFromPixmap(GrContext*, const SkPixmap&, SkBudgeted budgeted); + + /////////////////////////////////////////////////////////////////////////////////////////////// int width() const { return fWidth; } int height() const { return fHeight; } + SkISize dimensions() const { return SkISize::Make(fWidth, fHeight); } + SkIRect bounds() const { return SkIRect::MakeWH(fWidth, fHeight); } uint32_t uniqueID() const { return fUniqueID; } + SkAlphaType alphaType() const; + + /** + * Returns true fi the image will be drawn as a mask, with no intrinsic color of its own. + */ + bool isAlphaOnly() const; + bool isOpaque() const { return SkAlphaTypeIsOpaque(this->alphaType()); } + + /** + * Extracts YUV planes from the SkImage and stores them in client-provided memory. The sizes + * planes and rowBytes arrays are ordered [y, u, v]. + */ + bool readYUV8Planes(const SkISize[3], void* const planes[3], const size_t rowBytes[3], + SkYUVColorSpace) const; + + sk_sp makeShader(SkShader::TileMode, SkShader::TileMode, + const SkMatrix* localMatrix = nullptr) const; + + /** + * If the image has direct access to its pixels (i.e. they are in local RAM) + * return true, and if not null, return in the pixmap parameter the info about the + * images pixels. + * + * On failure, return false and ignore the pixmap parameter. + */ + bool peekPixels(SkPixmap* pixmap) const; + + /** + * Some images have to perform preliminary work in preparation for drawing. This can be + * decoding, uploading to a GPU, or other tasks. These happen automatically when an image + * is drawn, and often they are cached so that the cost is only paid the first time. + * + * Preroll() can be called before drawing to try to perform this prepatory work ahead of time. + * For images that have no such work, this returns instantly. Others may do some thing to + * prepare their cache and then return. + * + * If the image will drawn to a GPU-backed canvas or surface, pass the associated GrContext. + * If the image will be drawn to any other type of canvas or surface, pass null. + */ + void preroll(GrContext* = nullptr) const; + + // DEPRECATED - currently used by Canvas2DLayerBridge in Chromium. + GrTexture* getTexture() const; + + /** + * Returns true if the image is texture backed. + */ + bool isTextureBacked() const; /** - * Return the GrTexture that stores the image pixels. Calling getTexture - * does not affect the reference count of the GrTexture object. - * Will return NULL if the image does not use a texture. + * Retrieves the backend API handle of the texture. If flushPendingGrContextIO then the + * GrContext will issue to the backend API any deferred IO operations on the texture before + * returning. */ - GrTexture* getTexture(); + GrBackendObject getTextureHandle(bool flushPendingGrContextIO) const; - SkShader* newShaderClamp() const; - SkShader* newShader(SkShader::TileMode, SkShader::TileMode) const; + /** + * Hints to image calls where the system might cache computed intermediates (e.g. the results + * of decoding or a read-back from the GPU. Passing kAllow signals that the system's default + * behavior is fine. Passing kDisallow signals that caching should be avoided. + */ + enum CachingHint { + kAllow_CachingHint, + kDisallow_CachingHint, + }; + + /** + * Copy the pixels from the image into the specified buffer (pixels + rowBytes), + * converting them into the requested format (dstInfo). The image pixels are read + * starting at the specified (srcX,srcY) location. + * + * The specified ImageInfo and (srcX,srcY) offset specifies a source rectangle + * + * srcR.setXYWH(srcX, srcY, dstInfo.width(), dstInfo.height()); + * + * srcR is intersected with the bounds of the image. If this intersection is not empty, + * then we have two sets of pixels (of equal size). Replace the dst pixels with the + * corresponding src pixels, performing any colortype/alphatype transformations needed + * (in the case where the src and dst have different colortypes or alphatypes). + * + * This call can fail, returning false, for several reasons: + * - If srcR does not intersect the image bounds. + * - If the requested colortype/alphatype cannot be converted from the image's types. + */ + bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes, + int srcX, int srcY, CachingHint = kAllow_CachingHint) const; - void draw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*); + bool readPixels(const SkPixmap& dst, int srcX, int srcY, + CachingHint = kAllow_CachingHint) const; /** - * Draw the image, cropped to the src rect, to the dst rect of a canvas. - * If src is larger than the bounds of the image, the rest of the image is - * filled with transparent black pixels. + * Copy the pixels from this image into the dst pixmap, converting as needed into dst's + * colortype/alphatype. If the conversion cannot be performed, false is returned. * - * See SkCanvas::drawBitmapRectToRect for similar behavior. + * If dst's dimensions differ from the src dimension, the image will be scaled, applying the + * specified filter-quality. */ - void draw(SkCanvas*, const SkRect* src, const SkRect& dst, const SkPaint*); + bool scalePixels(const SkPixmap& dst, SkFilterQuality, CachingHint = kAllow_CachingHint) const; /** * Encode the image's pixels and return the result as a new SkData, which @@ -102,27 +271,171 @@ class SK_API SkImage : public SkRefCnt { * * If the image type cannot be encoded, or the requested encoder type is * not supported, this will return NULL. + * + * Note: this will attempt to encode the image's pixels in the specified format, + * even if the image returns a data from refEncoded(). That data will be ignored. */ - SkData* encode(SkImageEncoder::Type t = SkImageEncoder::kPNG_Type, - int quality = 80) const; + SkData* encode(SkEncodedImageFormat, int quality) const; +#ifdef SK_SUPPORT_LEGACY_IMAGE_ENCODER_CLASS + SkData* encode(SkImageEncoder::Type t, int quality) const { + return this->encode((SkEncodedImageFormat)t, quality); + } +#endif -protected: - SkImage(int width, int height) : - fWidth(width), - fHeight(height), - fUniqueID(NextUniqueID()) { + /** + * Encode the image and return the result as a caller-managed SkData. This will + * attempt to reuse existing encoded data (as returned by refEncoded). + * + * We defer to the SkPixelSerializer both for vetting existing encoded data + * (useEncodedData) and for encoding the image (encode) when no such data is + * present or is rejected by the serializer. + * + * If not specified, we use a default serializer which 1) always accepts existing data + * (in any format) and 2) encodes to PNG. + * + * If no compatible encoded data exists and encoding fails, this method will also + * fail (return NULL). + */ + SkData* encode(SkPixelSerializer* = nullptr) const; - SkASSERT(width >= 0); - SkASSERT(height >= 0); - } + /** + * If the image already has its contents in encoded form (e.g. PNG or JPEG), return a ref + * to that data (which the caller must call unref() on). The caller is responsible for calling + * unref on the data when they are done. + * + * If the image does not already has its contents in encoded form, return NULL. + * + * Note: to force the image to return its contents as encoded data, try calling encode(...). + */ + SkData* refEncoded() const; + + const char* toString(SkString*) const; + + /** + * Return a new image that is a subset of this image. The underlying implementation may + * share the pixels, or it may make a copy. + * + * If subset does not intersect the bounds of this image, or the copy/share cannot be made, + * NULL will be returned. + */ + sk_sp makeSubset(const SkIRect& subset) const; + + /** + * Ensures that an image is backed by a texture (when GrContext is non-null). If no + * transformation is required, the returned image may be the same as this image. If the this + * image is from a different GrContext, this will fail. + */ + sk_sp makeTextureImage(GrContext*) const; + + /** + * If the image is texture-backed this will make a raster copy of it (or nullptr if reading back + * the pixels fails). Otherwise, it returns the original image. + */ + sk_sp makeNonTextureImage() const; + /** + * Apply a given image filter to this image, and return the filtered result. + * + * The subset represents the active portion of this image. The return value is similarly an + * SkImage, with an active subset (outSubset). This is usually used with texture-backed + * images, where the texture may be approx-match and thus larger than the required size. + * + * clipBounds constrains the device-space extent of the image which may be produced to the + * given rect. + * + * offset is the amount to translate the resulting image relative to the src when it is drawn. + * This is an out-param. + * + * If the result image cannot be created, or the result would be transparent black, null + * is returned, in which case the offset and outSubset parameters should be ignored by the + * caller. + */ + sk_sp makeWithFilter(const SkImageFilter* filter, const SkIRect& subset, + const SkIRect& clipBounds, SkIRect* outSubset, + SkIPoint* offset) const; + + /** Drawing params for which a deferred texture image data should be optimized. */ + struct DeferredTextureImageUsageParams { + DeferredTextureImageUsageParams(const SkMatrix matrix, const SkFilterQuality quality, + int preScaleMipLevel) + : fMatrix(matrix), fQuality(quality), fPreScaleMipLevel(preScaleMipLevel) {} + SkMatrix fMatrix; + SkFilterQuality fQuality; + int fPreScaleMipLevel; + }; + + /** + * This method allows clients to capture the data necessary to turn a SkImage into a texture- + * backed image. If the original image is codec-backed this will decode into a format optimized + * for the context represented by the proxy. This method is thread safe with respect to the + * GrContext whence the proxy came. Clients allocate and manage the storage of the deferred + * texture data and control its lifetime. No cleanup is required, thus it is safe to simply free + * the memory out from under the data. + * + * The same method is used both for getting the size necessary for pre-uploaded texture data + * and for retrieving the data. The params array represents the set of draws over which to + * optimize the pre-upload data. + * + * When called with a null buffer this returns the size that the client must allocate in order + * to create deferred texture data for this image (or zero if this is an inappropriate + * candidate). The buffer allocated by the client should be 8 byte aligned. + * + * When buffer is not null this fills in the deferred texture data for this image in the + * provided buffer (assuming this is an appropriate candidate image and the buffer is + * appropriately aligned). Upon success the size written is returned, otherwise 0. + * + * dstColorSpace is the color space of the surface where this texture will ultimately be used. + * If the method determines that mip-maps are needed, this helps determine the correct strategy + * for building them (gamma-correct or not). + */ + size_t getDeferredTextureImageData(const GrContextThreadSafeProxy&, + const DeferredTextureImageUsageParams[], + int paramCnt, + void* buffer, + SkColorSpace* dstColorSpace = nullptr) const; + + /** + * Returns a texture-backed image from data produced in SkImage::getDeferredTextureImageData. + * The context must be the context that provided the proxy passed to + * getDeferredTextureImageData. + */ + static sk_sp MakeFromDeferredTextureImageData(GrContext*, const void*, SkBudgeted); + + // Helper functions to convert to SkBitmap + + enum LegacyBitmapMode { + kRO_LegacyBitmapMode, + kRW_LegacyBitmapMode, + }; + + /** + * Attempt to create a bitmap with the same pixels as the image. The result will always be + * a raster-backed bitmap (texture-backed bitmaps are DEPRECATED, and not supported here). + * + * If the mode is kRO (read-only), the resulting bitmap will be marked as immutable. + * + * On succcess, returns true. On failure, returns false and the bitmap parameter will be reset + * to empty. + */ + bool asLegacyBitmap(SkBitmap*, LegacyBitmapMode) const; + + /** + * Returns true if the image is backed by an image-generator or other src that creates + * (and caches) its pixels / texture on-demand. + */ + bool isLazyGenerated() const; + +protected: + SkImage(int width, int height, uint32_t uniqueID); private: + static sk_sp MakeTextureFromMipMap(GrContext*, const SkImageInfo&, + const GrMipLevel* texels, int mipLevelCount, + SkBudgeted, SkDestinationSurfaceColorMode); + const int fWidth; const int fHeight; const uint32_t fUniqueID; - static uint32_t NextUniqueID(); - typedef SkRefCnt INHERITED; }; diff --git a/libskia/include/core/SkImageDecoder.h b/libskia/include/core/SkImageDecoder.h deleted file mode 100644 index 72414589..00000000 --- a/libskia/include/core/SkImageDecoder.h +++ /dev/null @@ -1,543 +0,0 @@ - -/* - * Copyright 2006 The Android Open Source Project - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - - -#ifndef SkImageDecoder_DEFINED -#define SkImageDecoder_DEFINED - -#include "SkBitmap.h" -#include "SkImage.h" -#include "SkRect.h" -#include "SkRefCnt.h" -#include "SkTRegistry.h" -#include "SkTypes.h" - -class SkStream; -class SkStreamRewindable; - -/** \class SkImageDecoder - - Base class for decoding compressed images into a SkBitmap -*/ -class SkImageDecoder : public SkNoncopyable { -public: - virtual ~SkImageDecoder(); - - enum Format { - kUnknown_Format, - kBMP_Format, - kGIF_Format, - kICO_Format, - kJPEG_Format, - kPNG_Format, - kWBMP_Format, - kWEBP_Format, - - kLastKnownFormat = kWEBP_Format, - }; - - /** Return the format of image this decoder can decode. If this decoder can decode multiple - formats, kUnknown_Format will be returned. - */ - virtual Format getFormat() const; - - /** Return the format of the SkStreamRewindable or kUnknown_Format if it cannot be determined. - Rewinds the stream before returning. - */ - static Format GetStreamFormat(SkStreamRewindable*); - - /** Return a readable string of the Format provided. - */ - static const char* GetFormatName(Format); - - /** Return a readable string of the value returned by getFormat(). - */ - const char* getFormatName() const; - - /** Whether the decoder should skip writing zeroes to output if possible. - */ - bool getSkipWritingZeroes() const { return fSkipWritingZeroes; } - - /** Set to true if the decoder should skip writing any zeroes when - creating the output image. - This is a hint that may not be respected by the decoder. - It should only be used if it is known that the memory to write - to has already been set to 0; otherwise the resulting image will - have garbage. - This is ideal for images that contain a lot of completely transparent - pixels, but may be a performance hit for an image that has only a - few transparent pixels. - The default is false. - */ - void setSkipWritingZeroes(bool skip) { fSkipWritingZeroes = skip; } - - /** Returns true if the decoder should try to dither the resulting image. - The default setting is true. - */ - bool getDitherImage() const { return fDitherImage; } - - /** Set to true if the the decoder should try to dither the resulting image. - The default setting is true. - */ - void setDitherImage(bool dither) { fDitherImage = dither; } - - /** Returns true if the decoder should try to decode the - resulting image to a higher quality even at the expense of - the decoding speed. - */ - bool getPreferQualityOverSpeed() const { return fPreferQualityOverSpeed; } - - /** Set to true if the the decoder should try to decode the - resulting image to a higher quality even at the expense of - the decoding speed. - */ - void setPreferQualityOverSpeed(bool qualityOverSpeed) { - fPreferQualityOverSpeed = qualityOverSpeed; - } - - /** Set to true to require the decoder to return a bitmap with unpremultiplied - colors. The default is false, meaning the resulting bitmap will have its - colors premultiplied. - NOTE: Passing true to this function may result in a bitmap which cannot - be properly used by Skia. - */ - void setRequireUnpremultipliedColors(bool request) { - fRequireUnpremultipliedColors = request; - } - - /** Returns true if the decoder will only return bitmaps with unpremultiplied - colors. - */ - bool getRequireUnpremultipliedColors() const { return fRequireUnpremultipliedColors; } - - /** \class Peeker - - Base class for optional callbacks to retrieve meta/chunk data out of - an image as it is being decoded. - */ - class Peeker : public SkRefCnt { - public: - SK_DECLARE_INST_COUNT(Peeker) - - /** Return true to continue decoding, or false to indicate an error, which - will cause the decoder to not return the image. - */ - virtual bool peek(const char tag[], const void* data, size_t length) = 0; - private: - typedef SkRefCnt INHERITED; - }; - - Peeker* getPeeker() const { return fPeeker; } - Peeker* setPeeker(Peeker*); - - /** \class Chooser - - Base class for optional callbacks to choose an image from a format that - contains multiple images. - */ - class Chooser : public SkRefCnt { - public: - SK_DECLARE_INST_COUNT(Chooser) - - virtual void begin(int count) {} - virtual void inspect(int index, SkBitmap::Config config, int width, int height) {} - /** Return the index of the subimage you want, or -1 to choose none of them. - */ - virtual int choose() = 0; - - private: - typedef SkRefCnt INHERITED; - }; - - Chooser* getChooser() const { return fChooser; } - Chooser* setChooser(Chooser*); - - /** - * Optional table describing the caller's preferred config based on - * information about the src data. Each field should be set to the - * preferred config for a src described in the name of the field. The - * src attributes are described in terms of depth (8-index, - * 8bit-grayscale, or 8-bits/component) and whether there is per-pixel - * alpha (does not apply to grayscale). If the caller has no preference - * for a particular src type, its slot should be set to kNo_Config. - * - * NOTE ABOUT PREFERRED CONFIGS: - * If a config is preferred, either using a pref table or as a parameter - * to some flavor of decode, it is still at the discretion of the codec - * as to what output config is actually returned, as it may not be able - * to support the caller's preference. - * - * If a bitmap is decoded into SkBitmap::A8_Config, the resulting bitmap - * will either be a conversion of the grayscale in the case of a - * grayscale source or the alpha channel in the case of a source with - * an alpha channel. - */ - struct PrefConfigTable { - SkBitmap::Config fPrefFor_8Index_NoAlpha_src; - SkBitmap::Config fPrefFor_8Index_YesAlpha_src; - SkBitmap::Config fPrefFor_8Gray_src; - SkBitmap::Config fPrefFor_8bpc_NoAlpha_src; - SkBitmap::Config fPrefFor_8bpc_YesAlpha_src; - }; - - /** - * Set an optional table for specifying the caller's preferred config - * based on information about the src data. - * - * The default is no preference, which will assume the config set by - * decode is preferred. - */ - void setPrefConfigTable(const PrefConfigTable&); - - /** - * Do not use a PrefConfigTable to determine the output config. This - * is the default, so there is no need to call unless a PrefConfigTable - * was previously set. - */ - void resetPrefConfigTable() { fUsePrefTable = false; } - - SkBitmap::Allocator* getAllocator() const { return fAllocator; } - SkBitmap::Allocator* setAllocator(SkBitmap::Allocator*); - - // sample-size, if set to > 1, tells the decoder to return a smaller than - // original bitmap, sampling 1 pixel for every size pixels. e.g. if sample - // size is set to 3, then the returned bitmap will be 1/3 as wide and high, - // and will contain 1/9 as many pixels as the original. - // Note: this is a hint, and the codec may choose to ignore this, or only - // approximate the sample size. - int getSampleSize() const { return fSampleSize; } - void setSampleSize(int size); - - /** Reset the sampleSize to its default of 1 - */ - void resetSampleSize() { this->setSampleSize(1); } - - /** Decoding is synchronous, but for long decodes, a different thread can - call this method safely. This sets a state that the decoders will - periodically check, and if they see it changed to cancel, they will - cancel. This will result in decode() returning false. However, there is - no guarantee that the decoder will see the state change in time, so - it is possible that cancelDecode() will be called, but will be ignored - and decode() will return true (assuming no other problems were - encountered). - - This state is automatically reset at the beginning of decode(). - */ - void cancelDecode() { - // now the subclass must query shouldCancelDecode() to be informed - // of the request - fShouldCancelDecode = true; - } - - /** Passed to the decode method. If kDecodeBounds_Mode is passed, then - only the bitmap's width/height/config need be set. If kDecodePixels_Mode - is passed, then the bitmap must have pixels or a pixelRef. - */ - enum Mode { - kDecodeBounds_Mode, //!< only return width/height/config in bitmap - kDecodePixels_Mode //!< return entire bitmap (including pixels) - }; - - /** Given a stream, decode it into the specified bitmap. - If the decoder can decompress the image, it calls bitmap.setConfig(), - and then if the Mode is kDecodePixels_Mode, call allocPixelRef(), - which will allocated a pixelRef. To access the pixel memory, the codec - needs to call lockPixels/unlockPixels on the - bitmap. It can then set the pixels with the decompressed image. - * If the image cannot be decompressed, return false. After the - * decoding, the function converts the decoded config in bitmap - * to pref if possible. Whether a conversion is feasible is - * tested by Bitmap::canCopyTo(pref). - - If an SkBitmap::Allocator is installed via setAllocator, it will be - used to allocate the pixel memory. A clever allocator can be used - to allocate the memory from a cache, volatile memory, or even from - an existing bitmap's memory. - - If a Peeker is installed via setPeeker, it may be used to peek into - meta data during the decode. - - If a Chooser is installed via setChooser, it may be used to select - which image to return from a format that contains multiple images. - */ - bool decode(SkStream*, SkBitmap* bitmap, SkBitmap::Config pref, Mode); - bool decode(SkStream* stream, SkBitmap* bitmap, Mode mode) { - return this->decode(stream, bitmap, SkBitmap::kNo_Config, mode); - } - - /** - * Given a stream, build an index for doing tile-based decode. - * The built index will be saved in the decoder, and the image size will - * be returned in width and height. - * - * Return true for success or false on failure. - */ - bool buildTileIndex(SkStreamRewindable*, int *width, int *height); - - /** - * Decode a rectangle subset in the image. - * The method can only be called after buildTileIndex(). - * - * Return true for success. - * Return false if the index is never built or failing in decoding. - */ - bool decodeSubset(SkBitmap* bm, const SkIRect& subset, SkBitmap::Config pref); - - /** - * @Deprecated - * Use decodeSubset instead. - */ - bool decodeRegion(SkBitmap* bitmap, const SkIRect& rect, SkBitmap::Config pref) { - return this->decodeSubset(bitmap, rect, pref); - } - - /** Given a stream, this will try to find an appropriate decoder object. - If none is found, the method returns NULL. - */ - static SkImageDecoder* Factory(SkStreamRewindable*); - - /** Decode the image stored in the specified file, and store the result - in bitmap. Return true for success or false on failure. - - @param prefConfig If the PrefConfigTable is not set, prefer this config. - See NOTE ABOUT PREFERRED CONFIGS. - - @param format On success, if format is non-null, it is set to the format - of the decoded file. On failure it is ignored. - */ - static bool DecodeFile(const char file[], SkBitmap* bitmap, - SkBitmap::Config prefConfig, Mode, - Format* format = NULL); - static bool DecodeFile(const char file[], SkBitmap* bitmap) { - return DecodeFile(file, bitmap, SkBitmap::kNo_Config, - kDecodePixels_Mode, NULL); - } - /** Decode the image stored in the specified memory buffer, and store the - result in bitmap. Return true for success or false on failure. - - @param prefConfig If the PrefConfigTable is not set, prefer this config. - See NOTE ABOUT PREFERRED CONFIGS. - - @param format On success, if format is non-null, it is set to the format - of the decoded buffer. On failure it is ignored. - */ - static bool DecodeMemory(const void* buffer, size_t size, SkBitmap* bitmap, - SkBitmap::Config prefConfig, Mode, - Format* format = NULL); - static bool DecodeMemory(const void* buffer, size_t size, SkBitmap* bitmap){ - return DecodeMemory(buffer, size, bitmap, SkBitmap::kNo_Config, - kDecodePixels_Mode, NULL); - } - - /** - * Struct containing information about a pixel destination. - */ - struct Target { - /** - * Pre-allocated memory. - */ - void* fAddr; - - /** - * Rowbytes of the allocated memory. - */ - size_t fRowBytes; - }; - - /** Decode the image stored in the specified SkStreamRewindable, and store the result - in bitmap. Return true for success or false on failure. - - @param prefConfig If the PrefConfigTable is not set, prefer this config. - See NOTE ABOUT PREFERRED CONFIGS. - - @param format On success, if format is non-null, it is set to the format - of the decoded stream. On failure it is ignored. - */ - static bool DecodeStream(SkStreamRewindable* stream, SkBitmap* bitmap, - SkBitmap::Config prefConfig, Mode, - Format* format = NULL); - static bool DecodeStream(SkStreamRewindable* stream, SkBitmap* bitmap) { - return DecodeStream(stream, bitmap, SkBitmap::kNo_Config, - kDecodePixels_Mode, NULL); - } - - /** Return the default config for the running device. - Currently this used as a suggestion to image decoders that need to guess - what config they should decode into. - Default is kNo_Config, but this can be changed with SetDeviceConfig() - */ - static SkBitmap::Config GetDeviceConfig(); - /** Set the default config for the running device. - Currently this used as a suggestion to image decoders that need to guess - what config they should decode into. - Default is kNo_Config. - This can be queried with GetDeviceConfig() - */ - static void SetDeviceConfig(SkBitmap::Config); - -protected: - // must be overridden in subclasses. This guy is called by decode(...) - virtual bool onDecode(SkStream*, SkBitmap* bitmap, Mode) = 0; - - // If the decoder wants to support tiled based decoding, - // this method must be overridden. This guy is called by buildTileIndex(...) - virtual bool onBuildTileIndex(SkStreamRewindable*, int *width, int *height) { - return false; - } - - // If the decoder wants to support tiled based decoding, - // this method must be overridden. This guy is called by decodeRegion(...) - virtual bool onDecodeSubset(SkBitmap* bitmap, const SkIRect& rect) { - return false; - } - - /* - * Crop a rectangle from the src Bitmap to the dest Bitmap. src and dst are - * both sampled by sampleSize from an original Bitmap. - * - * @param dst the destination bitmap. - * @param src the source bitmap that is sampled by sampleSize from the - * original bitmap. - * @param sampleSize the sample size that src is sampled from the original bitmap. - * @param (dstX, dstY) the upper-left point of the dest bitmap in terms of - * the coordinate in the original bitmap. - * @param (width, height) the width and height of the unsampled dst. - * @param (srcX, srcY) the upper-left point of the src bitmap in terms of - * the coordinate in the original bitmap. - * @return bool Whether or not it succeeded. - */ - bool cropBitmap(SkBitmap *dst, SkBitmap *src, int sampleSize, - int dstX, int dstY, int width, int height, - int srcX, int srcY); - - /** - * Copy all fields on this decoder to the other decoder. Used by subclasses - * to decode a subimage using a different decoder, but with the same settings. - */ - void copyFieldsToOther(SkImageDecoder* other); - - /** - * Return the default preference being used by the current or latest call to - * decode. - */ - SkBitmap::Config getDefaultPref() { return fDefaultPref; } - - /** Can be queried from within onDecode, to see if the user (possibly in - a different thread) has requested the decode to cancel. If this returns - true, your onDecode() should stop and return false. - Each subclass needs to decide how often it can query this, to balance - responsiveness with performance. - - Calling this outside of onDecode() may return undefined values. - */ - -public: - bool shouldCancelDecode() const { return fShouldCancelDecode; } - -protected: - SkImageDecoder(); - - // helper function for decoders to handle the (common) case where there is only - // once choice available in the image file. - bool chooseFromOneChoice(SkBitmap::Config config, int width, int height) const; - - /* Helper for subclasses. Call this to allocate the pixel memory given the bitmap's - width/height/rowbytes/config. Returns true on success. This method handles checking - for an optional Allocator. - */ - bool allocPixelRef(SkBitmap*, SkColorTable*) const; - - /** - * The raw data of the src image. - */ - enum SrcDepth { - // Color-indexed. - kIndex_SrcDepth, - // Grayscale in 8 bits. - k8BitGray_SrcDepth, - // 8 bits per component. Used for 24 bit if there is no alpha. - k32Bit_SrcDepth, - }; - /** The subclass, inside onDecode(), calls this to determine the config of - the returned bitmap. SrcDepth and hasAlpha reflect the raw data of the - src image. This routine returns the caller's preference given - srcDepth and hasAlpha, or kNo_Config if there is no preference. - - Note: this also takes into account GetDeviceConfig(), so the subclass - need not call that. - */ - SkBitmap::Config getPrefConfig(SrcDepth, bool hasAlpha) const; - -private: - Peeker* fPeeker; - Chooser* fChooser; - SkBitmap::Allocator* fAllocator; - int fSampleSize; - SkBitmap::Config fDefaultPref; // use if fUsePrefTable is false - PrefConfigTable fPrefTable; // use if fUsePrefTable is true - bool fDitherImage; - bool fUsePrefTable; - bool fSkipWritingZeroes; - mutable bool fShouldCancelDecode; - bool fPreferQualityOverSpeed; - bool fRequireUnpremultipliedColors; -}; - -/** Calling newDecoder with a stream returns a new matching imagedecoder - instance, or NULL if none can be found. The caller must manage its ownership - of the stream as usual, calling unref() when it is done, as the returned - decoder may have called ref() (and if so, the decoder is responsible for - balancing its ownership when it is destroyed). - */ -class SkImageDecoderFactory : public SkRefCnt { -public: - SK_DECLARE_INST_COUNT(SkImageDecoderFactory) - - virtual SkImageDecoder* newDecoder(SkStreamRewindable*) = 0; - -private: - typedef SkRefCnt INHERITED; -}; - -class SkDefaultImageDecoderFactory : SkImageDecoderFactory { -public: - // calls SkImageDecoder::Factory(stream) - virtual SkImageDecoder* newDecoder(SkStreamRewindable* stream) { - return SkImageDecoder::Factory(stream); - } -}; - -// This macro declares a global (i.e., non-class owned) creation entry point -// for each decoder (e.g., CreateJPEGImageDecoder) -#define DECLARE_DECODER_CREATOR(codec) \ - SkImageDecoder *Create ## codec (); - -// This macro defines the global creation entry point for each decoder. Each -// decoder implementation that registers with the decoder factory must call it. -#define DEFINE_DECODER_CREATOR(codec) \ - SkImageDecoder *Create ## codec () { \ - return SkNEW( Sk ## codec ); \ - } - -// All the decoders known by Skia. Note that, depending on the compiler settings, -// not all of these will be available -DECLARE_DECODER_CREATOR(BMPImageDecoder); -DECLARE_DECODER_CREATOR(GIFImageDecoder); -DECLARE_DECODER_CREATOR(ICOImageDecoder); -DECLARE_DECODER_CREATOR(JPEGImageDecoder); -DECLARE_DECODER_CREATOR(PNGImageDecoder); -DECLARE_DECODER_CREATOR(WBMPImageDecoder); -DECLARE_DECODER_CREATOR(WEBPImageDecoder); - - -// Typedefs to make registering decoder and formatter callbacks easier. -// These have to be defined outside SkImageDecoder. :( -typedef SkTRegistry SkImageDecoder_DecodeReg; -typedef SkTRegistry SkImageDecoder_FormatReg; - -#endif diff --git a/libskia/include/core/SkImageDeserializer.h b/libskia/include/core/SkImageDeserializer.h new file mode 100644 index 00000000..ba142264 --- /dev/null +++ b/libskia/include/core/SkImageDeserializer.h @@ -0,0 +1,36 @@ +/* + * Copyright 2016 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkImageDeserializer_DEFINED +#define SkImageDeserializer_DEFINED + +#include "SkRefCnt.h" + +struct SkIRect; +class SkData; +class SkImage; + +class SK_API SkImageDeserializer { +public: + virtual ~SkImageDeserializer() {} + + /** + * Given a data containing serialized content, return an SkImage from it. + * + * @param data The data containing the encoded image. The subclass may ref this for later + * decoding, or read it and process it immediately. + * @param subset Optional rectangle represent the subset of the encoded data that is being + * requested to be turned into an image. + * @return The new image, or nullptr on failure. + * + * The default implementation is to call SkImage::MakeFromEncoded(...) + */ + virtual sk_sp makeFromData(SkData*, const SkIRect* subset); + virtual sk_sp makeFromMemory(const void* data, size_t length, const SkIRect* subset); +}; + +#endif diff --git a/libskia/include/core/SkImageEncoder.h b/libskia/include/core/SkImageEncoder.h index 5622eee7..17d06035 100644 --- a/libskia/include/core/SkImageEncoder.h +++ b/libskia/include/core/SkImageEncoder.h @@ -1,104 +1,74 @@ - /* * Copyright 2011 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ + #ifndef SkImageEncoder_DEFINED #define SkImageEncoder_DEFINED -#include "SkTypes.h" -#include "SkTRegistry.h" +#include "SkBitmap.h" +#include "SkEncodedImageFormat.h" +#include "SkStream.h" -class SkBitmap; -class SkData; -class SkWStream; +/** + * Encode SkPixmap in the given binary image format. + * + * @param dst results are written to this stream. + * @param src source pixels. + * @param format image format, not all formats are supported. + * @param quality range from 0-100, not all formats respect quality. + * + * @return false iff input is bad or format is unsupported. + * + * Will always return false if Skia is compiled without image + * encoders. + * + * For examples of encoding an image to a file or to a block of memory, + * see tools/sk_tool_utils.h. + */ +SK_API bool SkEncodeImage(SkWStream* dst, const SkPixmap& src, + SkEncodedImageFormat format, int quality); +/** + * The following helper function wraps SkEncodeImage(). + */ +inline bool SkEncodeImage(SkWStream* dst, const SkBitmap& src, SkEncodedImageFormat f, int q) { + SkAutoLockPixels autoLockPixels(src); + SkPixmap pixmap; + return src.peekPixels(&pixmap) && SkEncodeImage(dst, pixmap, f, q); +} +//TODO(halcanary): remove this code once all changes land. +#ifdef SK_SUPPORT_LEGACY_IMAGE_ENCODER_CLASS class SkImageEncoder { public: enum Type { - kUnknown_Type, - kBMP_Type, - kGIF_Type, - kICO_Type, - kJPEG_Type, - kPNG_Type, - kWBMP_Type, - kWEBP_Type, - }; - static SkImageEncoder* Create(Type); - - virtual ~SkImageEncoder(); - - /* Quality ranges from 0..100 */ - enum { - kDefaultQuality = 80 +#ifdef GOOGLE3 + kUnknown_Type = (int)SkEncodedImageFormat::kUnknown, +#endif + kBMP_Type = (int)SkEncodedImageFormat::kBMP, + kGIF_Type = (int)SkEncodedImageFormat::kGIF, + kICO_Type = (int)SkEncodedImageFormat::kICO, + kJPEG_Type = (int)SkEncodedImageFormat::kJPEG, + kPNG_Type = (int)SkEncodedImageFormat::kPNG, + kWBMP_Type = (int)SkEncodedImageFormat::kWBMP, + kWEBP_Type = (int)SkEncodedImageFormat::kWEBP, + kKTX_Type = (int)SkEncodedImageFormat::kKTX, }; - - /** - * Encode bitmap 'bm', returning the results in an SkData, at quality level - * 'quality' (which can be in range 0-100). If the bitmap cannot be - * encoded, return null. On success, the caller is responsible for - * calling unref() on the data when they are finished. - */ - SkData* encodeData(const SkBitmap&, int quality); - - /** - * Encode bitmap 'bm' in the desired format, writing results to - * file 'file', at quality level 'quality' (which can be in range - * 0-100). Returns false on failure. - */ - bool encodeFile(const char file[], const SkBitmap& bm, int quality); - - /** - * Encode bitmap 'bm' in the desired format, writing results to - * stream 'stream', at quality level 'quality' (which can be in - * range 0-100). Returns false on failure. - */ - bool encodeStream(SkWStream* stream, const SkBitmap& bm, int quality); - - static SkData* EncodeData(const SkBitmap&, Type, int quality); - static bool EncodeFile(const char file[], const SkBitmap&, Type, - int quality); - static bool EncodeStream(SkWStream*, const SkBitmap&, Type, - int quality); - -protected: - /** - * Encode bitmap 'bm' in the desired format, writing results to - * stream 'stream', at quality level 'quality' (which can be in - * range 0-100). - * - * This must be overridden by each SkImageEncoder implementation. - */ - virtual bool onEncode(SkWStream* stream, const SkBitmap& bm, int quality) = 0; -}; - -// This macro declares a global (i.e., non-class owned) creation entry point -// for each encoder (e.g., CreateJPEGImageEncoder) -#define DECLARE_ENCODER_CREATOR(codec) \ - SkImageEncoder *Create ## codec (); - -// This macro defines the global creation entry point for each encoder. Each -// encoder implementation that registers with the encoder factory must call it. -#define DEFINE_ENCODER_CREATOR(codec) \ - SkImageEncoder *Create ## codec () { \ - return SkNEW( Sk ## codec ); \ + static SkData* EncodeData(const SkBitmap& src, Type t, int quality) { + SkDynamicMemoryWStream buf; + return SkEncodeImage(&buf, src, (SkEncodedImageFormat)t, quality) + ? buf.detachAsData().release() : nullptr; } + static bool EncodeFile(const char path[], const SkBitmap& src, Type t, int quality) { + SkFILEWStream file(path); + return SkEncodeImage(&file, src, (SkEncodedImageFormat)t, quality); + } + static bool EncodeStream(SkWStream* dst, const SkBitmap& bm, Type t, int quality) { + return SkEncodeImage(dst, bm, (SkEncodedImageFormat)t, quality); + } +}; +#endif // SK_SUPPORT_LEGACY_IMAGE_ENCODER_CLASS -// All the encoders known by Skia. Note that, depending on the compiler settings, -// not all of these will be available -/** An ARGBImageEncoder will always write out - * bitmap.width() * bitmap.height() * 4 - * bytes. - */ -DECLARE_ENCODER_CREATOR(ARGBImageEncoder); -DECLARE_ENCODER_CREATOR(JPEGImageEncoder); -DECLARE_ENCODER_CREATOR(PNGImageEncoder); -DECLARE_ENCODER_CREATOR(WEBPImageEncoder); - -// Typedef to make registering encoder callback easier -// This has to be defined outside SkImageEncoder. :( -typedef SkTRegistry SkImageEncoder_EncodeReg; -#endif +#endif // SkImageEncoder_DEFINED diff --git a/libskia/include/core/SkImageFilter.h b/libskia/include/core/SkImageFilter.h index 398af90c..c2d72611 100644 --- a/libskia/include/core/SkImageFilter.h +++ b/libskia/include/core/SkImageFilter.h @@ -8,17 +8,22 @@ #ifndef SkImageFilter_DEFINED #define SkImageFilter_DEFINED +#include "../private/SkTArray.h" +#include "../private/SkTemplates.h" +#include "../private/SkMutex.h" +#include "SkColorSpace.h" +#include "SkFilterQuality.h" #include "SkFlattenable.h" +#include "SkMatrix.h" #include "SkRect.h" -class SkBitmap; +class GrContext; +class GrFragmentProcessor; class SkColorFilter; -class SkBaseDevice; -class SkMatrix; struct SkIPoint; -class SkShader; -class GrEffectRef; -class GrTexture; +class SkSpecialImage; +class SkImageFilterCache; +struct SkImageFilterCacheKey; /** * Base class for image filters. If one is installed in the paint, then @@ -29,83 +34,127 @@ class GrTexture; */ class SK_API SkImageFilter : public SkFlattenable { public: - SK_DECLARE_INST_COUNT(SkImageFilter) + // Extra information about the output of a filter DAG. For now, this is just the color space + // (of the original requesting device). This is used when constructing intermediate rendering + // surfaces, so that we ensure we land in a surface that's similar/compatible to the final + // consumer of the DAG's output. + class OutputProperties { + public: + explicit OutputProperties(SkColorSpace* colorSpace) : fColorSpace(colorSpace) {} + + SkColorSpace* colorSpace() const { return fColorSpace; } + + private: + // This will be a pointer to the device's color space, and our lifetime is bounded by + // the device, so we can store a bare pointer. + SkColorSpace* fColorSpace; + }; + + class Context { + public: + Context(const SkMatrix& ctm, const SkIRect& clipBounds, SkImageFilterCache* cache, + const OutputProperties& outputProperties) + : fCTM(ctm) + , fClipBounds(clipBounds) + , fCache(cache) + , fOutputProperties(outputProperties) + {} + + const SkMatrix& ctm() const { return fCTM; } + const SkIRect& clipBounds() const { return fClipBounds; } + SkImageFilterCache* cache() const { return fCache; } + const OutputProperties& outputProperties() const { return fOutputProperties; } + + private: + SkMatrix fCTM; + SkIRect fClipBounds; + SkImageFilterCache* fCache; + OutputProperties fOutputProperties; + }; class CropRect { public: enum CropEdge { kHasLeft_CropEdge = 0x01, kHasTop_CropEdge = 0x02, - kHasRight_CropEdge = 0x04, - kHasBottom_CropEdge = 0x08, + kHasWidth_CropEdge = 0x04, + kHasHeight_CropEdge = 0x08, kHasAll_CropEdge = 0x0F, }; CropRect() {} - explicit CropRect(const SkRect& rect, uint32_t flags = kHasAll_CropEdge) : fRect(rect), fFlags(flags) {} + explicit CropRect(const SkRect& rect, uint32_t flags = kHasAll_CropEdge) + : fRect(rect), fFlags(flags) {} uint32_t flags() const { return fFlags; } const SkRect& rect() const { return fRect; } +#ifndef SK_IGNORE_TO_STRING + void toString(SkString* str) const; +#endif + + /** + * Apply this cropRect to the imageBounds. If a given edge of the cropRect is not + * set, then the corresponding edge from imageBounds will be used. If "embiggen" + * is true, the crop rect is allowed to enlarge the size of the rect, otherwise + * it may only reduce the rect. Filters that can affect transparent black should + * pass "true", while all other filters should pass "false". + * + * Note: imageBounds is in "device" space, as the output cropped rectangle will be, + * so the matrix is ignored for those. It is only applied the croprect's bounds. + */ + void applyTo(const SkIRect& imageBounds, const SkMatrix&, bool embiggen, + SkIRect* cropped) const; + private: SkRect fRect; uint32_t fFlags; }; - class Proxy { - public: - virtual ~Proxy() {}; - - virtual SkBaseDevice* createDevice(int width, int height) = 0; - // returns true if the proxy can handle this filter natively - virtual bool canHandleImageFilter(SkImageFilter*) = 0; - // returns true if the proxy handled the filter itself. if this returns - // false then the filter's code will be called. - virtual bool filterImage(SkImageFilter*, const SkBitmap& src, - const SkMatrix& ctm, - SkBitmap* result, SkIPoint* offset) = 0; + enum TileUsage { + kPossible_TileUsage, //!< the created device may be drawn tiled + kNever_TileUsage, //!< the created device will never be drawn tiled }; /** - * Request a new (result) image to be created from the src image. - * If the src has no pixels (isNull()) then the request just wants to - * receive the config and width/height of the result. + * Request a new filtered image to be created from the src image. * - * The matrix is the current matrix on the canvas. + * The context contains the environment in which the filter is occurring. + * It includes the clip bounds, CTM and cache. * * Offset is the amount to translate the resulting image relative to the * src when it is drawn. This is an out-param. * - * If the result image cannot be created, return false, in which case both - * the result and offset parameters will be ignored by the caller. - */ - bool filterImage(Proxy*, const SkBitmap& src, const SkMatrix& ctm, - SkBitmap* result, SkIPoint* offset); - - /** - * Given the src bounds of an image, this returns the bounds of the result - * image after the filter has been applied. + * If the result image cannot be created, or the result would be + * transparent black, return null, in which case the offset parameter + * should be ignored by the caller. + * + * TODO: Right now the imagefilters sometimes return empty result bitmaps/ + * specialimages. That doesn't seem quite right. */ - bool filterBounds(const SkIRect& src, const SkMatrix& ctm, SkIRect* dst); + sk_sp filterImage(SkSpecialImage* src, const Context&, SkIPoint* offset) const; + enum MapDirection { + kForward_MapDirection, + kReverse_MapDirection + }; /** - * Returns true if the filter can be processed on the GPU. This is most - * often used for multi-pass effects, where intermediate results must be - * rendered to textures. For single-pass effects, use asNewEffect(). - * The default implementation returns asNewEffect(NULL, NULL, SkMatrix::I(), - * SkIRect()). + * Map a device-space rect recursively forward or backward through the + * filter DAG. kForward_MapDirection is used to determine which pixels of + * the destination canvas a source image rect would touch after filtering. + * kReverse_MapDirection is used to determine which rect of the source + * image would be required to fill the given rect (typically, clip bounds). + * Used for clipping and temp-buffer allocations, so the result need not + * be exact, but should never be smaller than the real answer. The default + * implementation recursively unions all input bounds, or returns the + * source rect if no inputs. */ - virtual bool canFilterImageGPU() const; + SkIRect filterBounds(const SkIRect& src, const SkMatrix& ctm, + MapDirection = kReverse_MapDirection) const; - /** - * Process this image filter on the GPU. This is most often used for - * multi-pass effects, where intermediate results must be rendered to - * textures. For single-pass effects, use asNewEffect(). src is the - * source image for processing, as a texture-backed bitmap. result is - * the destination bitmap, which should contain a texture-backed pixelref - * on success. offset is the amount to translate the resulting image - * relative to the src when it is drawn. The default implementation does - * single-pass processing using asNewEffect(). - */ - virtual bool filterImageGPU(Proxy*, const SkBitmap& src, const SkMatrix& ctm, - SkBitmap* result, SkIPoint* offset); +#if SK_SUPPORT_GPU + static sk_sp DrawWithFP(GrContext* context, + sk_sp fp, + const SkIRect& bounds, + const OutputProperties& outputProperties); +#endif /** * Returns whether this image filter is a color filter and puts the color filter into the @@ -114,58 +163,125 @@ class SK_API SkImageFilter : public SkFlattenable { * If this returns true, then if filterPtr is not null, it must be set to a ref'd colorfitler * (i.e. it may not be set to NULL). */ - virtual bool asColorFilter(SkColorFilter** filterPtr) const; + bool isColorFilterNode(SkColorFilter** filterPtr) const { + return this->onIsColorFilterNode(filterPtr); + } + + // DEPRECATED : use isColorFilterNode() instead + bool asColorFilter(SkColorFilter** filterPtr) const { + return this->isColorFilterNode(filterPtr); + } + + static sk_sp MakeBlur(SkScalar sigmaX, SkScalar sigmaY, + sk_sp input, + const CropRect* cropRect = nullptr); + + /** + * Returns true (and optionally returns a ref'd filter) if this imagefilter can be completely + * replaced by the returned colorfilter. i.e. the two effects will affect drawing in the + * same way. + */ + bool asAColorFilter(SkColorFilter** filterPtr) const; /** * Returns the number of inputs this filter will accept (some inputs can * be NULL). */ - int countInputs() const { return fInputCount; } + int countInputs() const { return fInputs.count(); } /** * Returns the input filter at a given index, or NULL if no input is * connected. The indices used are filter-specific. */ SkImageFilter* getInput(int i) const { - SkASSERT(i < fInputCount); - return fInputs[i]; + SkASSERT(i < fInputs.count()); + return fInputs[i].get(); } /** * Returns whether any edges of the crop rect have been set. The crop * rect is set at construction time, and determines which pixels from the - * input image will be processed. The size of the crop rect should be + * input image will be processed, and which pixels in the output image will be allowed. + * The size of the crop rect should be * used as the size of the destination image. The origin of this rect * should be used to offset access to the input images, and should also - * be added to the "offset" parameter in onFilterImage and - * filterImageGPU(). (The latter ensures that the resulting buffer is - * drawn in the correct location.) + * be added to the "offset" parameter in onFilterImage. */ bool cropRectIsSet() const { return fCropRect.flags() != 0x0; } + CropRect getCropRect() const { return fCropRect; } + + // Default impl returns union of all input bounds. + virtual SkRect computeFastBounds(const SkRect&) const; + + // Can this filter DAG compute the resulting bounds of an object-space rectangle? + bool canComputeFastBounds() const; + + /** + * If this filter can be represented by another filter + a localMatrix, return that filter, + * else return null. + */ + sk_sp makeWithLocalMatrix(const SkMatrix&) const; + + /** + * ImageFilters can natively handle scaling and translate components in the CTM. Only some of + * them can handle affine (or more complex) matrices. This call returns true iff the filter + * and all of its (non-null) inputs can handle these more complex matrices. + */ + bool canHandleComplexCTM() const; + + /** + * Return an imagefilter which transforms its input by the given matrix. + */ + static sk_sp MakeMatrixFilter(const SkMatrix& matrix, + SkFilterQuality quality, + sk_sp input); + + SK_TO_STRING_PUREVIRT() SK_DEFINE_FLATTENABLE_TYPE(SkImageFilter) + SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP() protected: - SkImageFilter(int inputCount, SkImageFilter** inputs, const CropRect* cropRect = NULL); + class Common { + public: + /** + * Attempt to unflatten the cropRect and the expected number of input filters. + * If any number of input filters is valid, pass -1. + * If this fails (i.e. corrupt buffer or contents) then return false and common will + * be left uninitialized. + * If this returns true, then inputCount() is the number of found input filters, each + * of which may be NULL or a valid imagefilter. + */ + bool unflatten(SkReadBuffer&, int expectedInputs); - // Convenience constructor for 1-input filters. - explicit SkImageFilter(SkImageFilter* input, const CropRect* cropRect = NULL); + const CropRect& cropRect() const { return fCropRect; } + int inputCount() const { return fInputs.count(); } + sk_sp* inputs() const { return fInputs.get(); } + + sk_sp getInput(int index) const { return fInputs[index]; } + + private: + CropRect fCropRect; + // most filters accept at most 2 input-filters + SkAutoSTArray<2, sk_sp> fInputs; + + void allocInputs(int count); + }; - // Convenience constructor for 2-input filters. - SkImageFilter(SkImageFilter* input1, SkImageFilter* input2, const CropRect* cropRect = NULL); + SkImageFilter(sk_sp* inputs, int inputCount, const CropRect* cropRect); virtual ~SkImageFilter(); /** - * Constructs a new SkImageFilter read from an SkFlattenableReadBuffer object. + * Constructs a new SkImageFilter read from an SkReadBuffer object. * * @param inputCount The exact number of inputs expected for this SkImageFilter object. * -1 can be used if the filter accepts any number of inputs. - * @param rb SkFlattenableReadBuffer object from which the SkImageFilter is read. + * @param rb SkReadBuffer object from which the SkImageFilter is read. */ - explicit SkImageFilter(int inputCount, SkFlattenableReadBuffer& rb); + explicit SkImageFilter(int inputCount, SkReadBuffer& rb); - virtual void flatten(SkFlattenableWriteBuffer& wb) const SK_OVERRIDE; + void flatten(SkWriteBuffer&) const override; /** * This is the virtual which should be overridden by the derived class @@ -179,45 +295,125 @@ class SK_API SkImageFilter : public SkFlattenable { * Offset is the amount to translate the resulting image relative to the * src when it is drawn. This is an out-param. * - * If the result image cannot be created, this should false, in which - * case both the result and offset parameters will be ignored by the - * caller. + * If the result image cannot be created (either because of error or if, say, the result + * is entirely clipped out), this should return nullptr. + * Callers that affect transparent black should explicitly handle nullptr + * results and press on. In the error case this behavior will produce a better result + * than nothing and is necessary for the clipped out case. + * If the return value is nullptr then offset should be ignored. */ - virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&, - SkBitmap* result, SkIPoint* offset); - // Default impl copies src into dst and returns true - virtual bool onFilterBounds(const SkIRect&, const SkMatrix&, SkIRect*); - - // Applies "matrix" to the crop rect, and sets "rect" to the intersection of - // "rect" and the transformed crop rect. If there is no overlap, returns - // false and leaves "rect" unchanged. - bool applyCropRect(SkIRect* rect, const SkMatrix& matrix) const; + virtual sk_sp onFilterImage(SkSpecialImage* src, const Context&, + SkIPoint* offset) const = 0; /** - * Returns true if the filter can be expressed a single-pass - * GrEffect, used to process this filter on the GPU, or false if - * not. - * - * If effect is non-NULL, a new GrEffect instance is stored - * in it. The caller assumes ownership of the stage, and it is up to the - * caller to unref it. + * This function recurses into its inputs with the given rect (first + * argument), calls filterBounds() with the given map direction on each, + * and returns the union of those results. If a derived class has special + * recursion requirements (e.g., it has an input which does not participate + * in bounds computation), it can be overridden here. * - * The effect can assume its vertexCoords space maps 1-to-1 with texels - * in the texture. "matrix" is a transformation to apply to filter - * parameters before they are used in the effect. Note that this function - * will be called with (NULL, NULL, SkMatrix::I()) to query for support, - * so returning "true" indicates support for all possible matrices. + * Note that this function is *not* responsible for mapping the rect for + * this node's filter bounds requirements (i.e., calling + * onFilterNodeBounds()); that is handled by filterBounds(). + */ + virtual SkIRect onFilterBounds(const SkIRect&, const SkMatrix&, MapDirection) const; + + /** + * Performs a forwards or reverse mapping of the given rect to accommodate + * this filter's margin requirements. kForward_MapDirection is used to + * determine the destination pixels which would be touched by filtering + * the given given source rect (e.g., given source bitmap bounds, + * determine the optimal bounds of the filtered offscreen bitmap). + * kReverse_MapDirection is used to determine which pixels of the + * input(s) would be required to fill the given destination rect + * (e.g., clip bounds). NOTE: these operations may not be the + * inverse of the other. For example, blurring expands the given rect + * in both forward and reverse directions. Unlike + * onFilterBounds(), this function is non-recursive. */ - virtual bool asNewEffect(GrEffectRef** effect, - GrTexture*, - const SkMatrix& matrix, - const SkIRect& bounds) const; + virtual SkIRect onFilterNodeBounds(const SkIRect&, const SkMatrix&, MapDirection) const; + + // Helper function which invokes filter processing on the input at the + // specified "index". If the input is null, it returns "src" and leaves + // "offset" untouched. If the input is non-null, it + // calls filterImage() on that input, and returns the result. + sk_sp filterInput(int index, + SkSpecialImage* src, + const Context&, + SkIPoint* offset) const; + + /** + * Return true (and return a ref'd colorfilter) if this node in the DAG is just a + * colorfilter w/o CropRect constraints. + */ + virtual bool onIsColorFilterNode(SkColorFilter** /*filterPtr*/) const { + return false; + } + + /** + * Override this to describe the behavior of your subclass - as a leaf node. The caller will + * take care of calling your inputs (and return false if any of them could not handle it). + */ + virtual bool onCanHandleComplexCTM() const { return false; } + + /** Given a "srcBounds" rect, computes destination bounds for this filter. + * "dstBounds" are computed by transforming the crop rect by the context's + * CTM, applying it to the initial bounds, and intersecting the result with + * the context's clip bounds. "srcBounds" (if non-null) are computed by + * intersecting the initial bounds with "dstBounds", to ensure that we never + * sample outside of the crop rect (this restriction may be relaxed in the + * future). + */ + bool applyCropRect(const Context&, const SkIRect& srcBounds, SkIRect* dstBounds) const; + + /** A variant of the above call which takes the original source bitmap and + * source offset. If the resulting crop rect is not entirely contained by + * the source bitmap's bounds, it creates a new bitmap in "result" and + * pads the edges with transparent black. In that case, the srcOffset is + * modified to be the same as the bounds, since no further adjustment is + * needed by the caller. This version should only be used by filters + * which are not capable of processing a smaller source bitmap into a + * larger destination. + */ + sk_sp applyCropRect(const Context&, SkSpecialImage* src, SkIPoint* srcOffset, + SkIRect* bounds) const; + + /** + * Creates a modified Context for use when recursing up the image filter DAG. + * The clip bounds are adjusted to accommodate any margins that this + * filter requires by calling this node's + * onFilterNodeBounds(..., kReverse_MapDirection). + */ + Context mapContext(const Context& ctx) const; private: - typedef SkFlattenable INHERITED; - int fInputCount; - SkImageFilter** fInputs; + friend class SkGraphics; + static void PurgeCache(); + + void init(sk_sp* inputs, int inputCount, const CropRect* cropRect); + + bool usesSrcInput() const { return fUsesSrcInput; } + virtual bool affectsTransparentBlack() const { return false; } + + SkAutoSTArray<2, sk_sp> fInputs; + + bool fUsesSrcInput; CropRect fCropRect; + uint32_t fUniqueID; // Globally unique + mutable SkTArray fCacheKeys; + mutable SkMutex fMutex; + typedef SkFlattenable INHERITED; }; +/** + * Helper to unflatten the common data, and return NULL if we fail. + */ +#define SK_IMAGEFILTER_UNFLATTEN_COMMON(localVar, expectedCount) \ + Common localVar; \ + do { \ + if (!localVar.unflatten(buffer, expectedCount)) { \ + return NULL; \ + } \ + } while (0) + #endif diff --git a/libskia/include/core/SkImageFilterUtils.h b/libskia/include/core/SkImageFilterUtils.h deleted file mode 100644 index b3921cda..00000000 --- a/libskia/include/core/SkImageFilterUtils.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2013 The Android Open Source Project - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef SkImageFilterUtils_DEFINED -#define SkImageFilterUtils_DEFINED - -#if SK_SUPPORT_GPU - -#include "SkImageFilter.h" - -class SkBitmap; -class GrTexture; -class SkImageFilter; - -class SK_API SkImageFilterUtils { -public: - /** - * Wrap the given texture in a texture-backed SkBitmap. - */ - static bool WrapTexture(GrTexture* texture, int width, int height, SkBitmap* result); - - /** - * Recursively evaluate the given filter on the GPU. If filter is NULL, - * this function returns src. If the filter has no GPU implementation, it - * will be processed in software and uploaded to the GPU. - */ - static bool GetInputResultGPU(SkImageFilter* filter, SkImageFilter::Proxy* proxy, - const SkBitmap& src, const SkMatrix& ctm, SkBitmap* result, - SkIPoint* offset); -}; - -#endif - -#endif diff --git a/libskia/include/core/SkImageGenerator.h b/libskia/include/core/SkImageGenerator.h index 220973a0..e775d9e0 100644 --- a/libskia/include/core/SkImageGenerator.h +++ b/libskia/include/core/SkImageGenerator.h @@ -8,45 +8,30 @@ #ifndef SkImageGenerator_DEFINED #define SkImageGenerator_DEFINED -#include "SkDiscardableMemory.h" +#include "SkBitmap.h" +#include "SkColor.h" #include "SkImageInfo.h" +#include "SkYUVSizeInfo.h" +class GrContext; +class GrContextThreadSafeProxy; +class GrTexture; +class GrSamplerParams; class SkBitmap; class SkData; +class SkImage; class SkImageGenerator; +class SkMatrix; +class SkPaint; +class SkPicture; -/** - * Takes ownership of SkImageGenerator. If this method fails for - * whatever reason, it will return false and immediatetely delete - * the generator. If it succeeds, it will modify destination - * bitmap. - * - * If generator is NULL, will safely return false. - * - * If this fails or when the SkDiscardablePixelRef that is - * installed into destination is destroyed, it will call - * SkDELETE() on the generator. Therefore, generator should be - * allocated with SkNEW() or SkNEW_ARGS(). - * - * @param destination Upon success, this bitmap will be - * configured and have a pixelref installed. - * - * @param factory If not NULL, this object will be used as a - * source of discardable memory when decoding. If NULL, then - * SkDiscardableMemory::Create() will be called. - * - * @return true iff successful. - */ -SK_API bool SkInstallDiscardablePixelRef(SkImageGenerator* generator, - SkBitmap* destination, - SkDiscardableMemory::Factory* factory = NULL); - +#ifdef SK_SUPPORT_LEGACY_REFENCODEDDATA_NOCTX + #define SK_REFENCODEDDATA_CTXPARAM +#else + #define SK_REFENCODEDDATA_CTXPARAM GrContext* ctx +#endif -/** - * An interface that allows a purgeable PixelRef (such as a - * SkDiscardablePixelRef) to decode and re-decode an image as needed. - */ -class SK_API SkImageGenerator { +class SK_API SkImageGenerator : public SkNoncopyable { public: /** * The PixelRef which takes ownership of this SkImageGenerator @@ -54,25 +39,29 @@ class SK_API SkImageGenerator { */ virtual ~SkImageGenerator() { } + uint32_t uniqueID() const { return fUniqueID; } + /** * Return a ref to the encoded (i.e. compressed) representation, - * of this data. + * of this data. If the GrContext is non-null, then the caller is only interested in + * gpu-specific formats, so the impl may return null even if they have encoded data, + * assuming they know it is not suitable for the gpu. * * If non-NULL is returned, the caller is responsible for calling * unref() on the data when it is finished. */ - virtual SkData* refEncodedData() { return NULL; } + SkData* refEncodedData(GrContext* ctx = nullptr) { +#ifdef SK_SUPPORT_LEGACY_REFENCODEDDATA_NOCTX + return this->onRefEncodedData(); +#else + return this->onRefEncodedData(ctx); +#endif + } /** - * Return some information about the image, allowing the owner of - * this object to allocate pixels. - * - * Repeated calls to this function should give the same results, - * allowing the PixelRef to be immutable. - * - * @return false if anything goes wrong. + * Return the ImageInfo associated with this generator. */ - virtual bool getInfo(SkImageInfo* info) = 0; + const SkImageInfo& getInfo() const { return fInfo; } /** * Decode into the given pixels, a block of memory of size at @@ -90,12 +79,222 @@ class SK_API SkImageGenerator { * different output-configs, which the implementation can * decide to support or not. * - * @return false if anything goes wrong or if the image info is - * unsupported. + * A size that does not match getInfo() implies a request + * to scale. If the generator cannot perform this scale, + * it will return kInvalidScale. + * + * If info is kIndex8_SkColorType, then the caller must provide storage for up to 256 + * SkPMColor values in ctable. On success the generator must copy N colors into that storage, + * (where N is the logical number of table entries) and set ctableCount to N. + * + * If info is not kIndex8_SkColorType, then the last two parameters may be NULL. If ctableCount + * is not null, it will be set to 0. + * + * @return true on success. + */ + bool getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, + SkPMColor ctable[], int* ctableCount); + + /** + * Simplified version of getPixels() that asserts that info is NOT kIndex8_SkColorType and + * uses the default Options. + */ + bool getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes); + + /** + * If decoding to YUV is supported, this returns true. Otherwise, this + * returns false and does not modify any of the parameters. + * + * @param sizeInfo Output parameter indicating the sizes and required + * allocation widths of the Y, U, and V planes. + * @param colorSpace Output parameter. + */ + bool queryYUV8(SkYUVSizeInfo* sizeInfo, SkYUVColorSpace* colorSpace) const; + + /** + * Returns true on success and false on failure. + * This always attempts to perform a full decode. If the client only + * wants size, it should call queryYUV8(). + * + * @param sizeInfo Needs to exactly match the values returned by the + * query, except the WidthBytes may be larger than the + * recommendation (but not smaller). + * @param planes Memory for each of the Y, U, and V planes. + */ + bool getYUV8Planes(const SkYUVSizeInfo& sizeInfo, void* planes[3]); + + /** + * If the generator can natively/efficiently return its pixels as a GPU image (backed by a + * texture) this will return that image. If not, this will return NULL. + * + * Regarding the GrContext parameter: + * + * The caller may pass NULL for the context. In that case the generator may assume that its + * internal context is current. If it has no internal context, then it should just return + * null. + * + * If the caller passes a non-null context, then the generator should only succeed if: + * - it has no intrinsic context, and will use the caller's + * - its internal context is the same + * - it can somehow convert its texture into one that is valid for the provided context. + */ + GrTexture* generateTexture(GrContext*, const SkIRect* subset = nullptr); + + struct SupportedSizes { + SkISize fSizes[2]; + }; + + /** + * Some generators can efficiently scale their contents. If this is supported, the generator + * may only support certain scaled dimensions. Call this with the desired scale factor, + * and it will return true if scaling is supported, and in supportedSizes[] it will return + * the nearest supported dimensions. + * + * If no native scaling is supported, or scale is invalid (e.g. scale <= 0 || scale > 1) + * this will return false, and the supportedsizes will be undefined. */ - virtual bool getPixels(const SkImageInfo& info, - void* pixels, - size_t rowBytes) = 0; + bool computeScaledDimensions(SkScalar scale, SupportedSizes*); + + /** + * Scale the generator's pixels to fit into scaledSize. + * This routine also support retrieving only a subset of the pixels. That subset is specified + * by the following rectangle (in the scaled space): + * + * subset = SkIRect::MakeXYWH(subsetOrigin.x(), subsetOrigin.y(), + * subsetPixels.width(), subsetPixels.height()) + * + * If subset is not contained inside the scaledSize, this returns false. + * + * whole = SkIRect::MakeWH(scaledSize.width(), scaledSize.height()) + * if (!whole.contains(subset)) { + * return false; + * } + * + * If the requested colortype/alphatype in pixels is not supported, + * or the requested scaledSize is not supported, or the generator encounters an error, + * this returns false. + */ + bool generateScaledPixels(const SkISize& scaledSize, const SkIPoint& subsetOrigin, + const SkPixmap& subsetPixels); + + bool generateScaledPixels(const SkPixmap& scaledPixels) { + return this->generateScaledPixels(SkISize::Make(scaledPixels.width(), + scaledPixels.height()), + SkIPoint::Make(0, 0), scaledPixels); + } + + /** + * External generator API: provides efficient access to externally-managed image data. + * + * Skia calls accessScaledPixels() during rasterization, to gain temporary access to + * the external pixel data. When done, the provided callback is invoked to release the + * associated resources. + * + * @param srcRect the source rect in use for the current draw + * @param totalMatrix full matrix in effect (mapping srcRect -> device space) + * @param quality the SkFilterQuality requested for rasterization. + * @param rec out param, expected to be set when the call succeeds: + * + * - fPixmap external pixel data + * - fSrcRect is an adjusted srcRect + * - fQuality is the adjusted filter quality + * - fReleaseProc pixmap release callback, same signature as the + * SkBitmap::installPixels() callback + * - fReleaseCtx opaque release context argument + * + * @return true on success, false otherwise (error or if this API is not supported; + * in this case Skia will fall back to its internal scaling and caching + * heuristics) + * + * Implementors can return pixmaps with a different size than requested, by adjusting the + * src rect. The contract is that Skia will observe the adjusted src rect, and will map it + * to the same dest as the original draw (the impl doesn't get to control the destination). + * + */ + + struct ScaledImageRec { + SkPixmap fPixmap; + SkRect fSrcRect; + SkFilterQuality fQuality; + + using ReleaseProcT = void (*)(void* pixels, void* releaseCtx); + + ReleaseProcT fReleaseProc; + void* fReleaseCtx; + }; + + bool accessScaledImage(const SkRect& srcRect, const SkMatrix& totalMatrix, + SkFilterQuality quality, ScaledImageRec* rec); + + /** + * If the default image decoder system can interpret the specified (encoded) data, then + * this returns a new ImageGenerator for it. Otherwise this returns NULL. Either way + * the caller is still responsible for managing their ownership of the data. + */ + static SkImageGenerator* NewFromEncoded(SkData*); + + /** Return a new image generator backed by the specified picture. If the size is empty or + * the picture is NULL, this returns NULL. + * The optional matrix and paint arguments are passed to drawPicture() at rasterization + * time. + */ + static SkImageGenerator* NewFromPicture(const SkISize&, const SkPicture*, const SkMatrix*, + const SkPaint*); + + bool tryGenerateBitmap(SkBitmap* bm, const SkImageInfo& info, SkBitmap::Allocator* allocator) { + return this->tryGenerateBitmap(bm, &info, allocator); + } + void generateBitmap(SkBitmap* bm, const SkImageInfo& info) { + if (!this->tryGenerateBitmap(bm, &info, nullptr)) { + sk_throw(); + } + } + +protected: + enum { + kNeedNewImageUniqueID = 0 + }; + + SkImageGenerator(const SkImageInfo& info, uint32_t uniqueId = kNeedNewImageUniqueID); + + virtual SkData* onRefEncodedData(SK_REFENCODEDDATA_CTXPARAM); + + virtual bool onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, + SkPMColor ctable[], int* ctableCount); + + virtual bool onQueryYUV8(SkYUVSizeInfo*, SkYUVColorSpace*) const { + return false; + } + virtual bool onGetYUV8Planes(const SkYUVSizeInfo&, void*[3] /*planes*/) { + return false; + } + + virtual GrTexture* onGenerateTexture(GrContext*, const SkIRect*) { + return nullptr; + } + + virtual bool onComputeScaledDimensions(SkScalar, SupportedSizes*) { + return false; + } + virtual bool onGenerateScaledPixels(const SkISize&, const SkIPoint&, const SkPixmap&) { + return false; + } + + virtual bool onAccessScaledImage(const SkRect&, const SkMatrix&, SkFilterQuality, + ScaledImageRec*) { + return false; + } + + bool tryGenerateBitmap(SkBitmap* bm, const SkImageInfo* optionalInfo, SkBitmap::Allocator*); + +private: + const SkImageInfo fInfo; + const uint32_t fUniqueID; + + // This is our default impl, which may be different on different platforms. + // It is called from NewFromEncoded() after it has checked for any runtime factory. + // The SkData will never be NULL, as that will have been checked by NewFromEncoded. + static SkImageGenerator* NewFromEncodedImpl(SkData*); }; #endif // SkImageGenerator_DEFINED diff --git a/libskia/include/core/SkImageInfo.h b/libskia/include/core/SkImageInfo.h index bd63fccb..f8582d65 100644 --- a/libskia/include/core/SkImageInfo.h +++ b/libskia/include/core/SkImageInfo.h @@ -8,21 +8,19 @@ #ifndef SkImageInfo_DEFINED #define SkImageInfo_DEFINED -#include "SkTypes.h" +#include "SkColorSpace.h" +#include "SkMath.h" +#include "SkRect.h" +#include "SkSize.h" -class SkFlattenableWriteBuffer; -class SkFlattenableReadBuffer; +class SkReadBuffer; +class SkWriteBuffer; /** - * Describes how to interpret the alpha compoent of a pixel. + * Describes how to interpret the alpha component of a pixel. */ enum SkAlphaType { - /** - * All pixels should be treated as opaque, regardless of the value stored - * in their alpha field. Used for legacy images that wrote 0 or garbarge - * in their alpha field, but intended the RGB to be treated as opaque. - */ - kIgnore_SkAlphaType, + kUnknown_SkAlphaType, /** * All pixels are stored as opaque. This differs slightly from kIgnore in @@ -51,94 +49,303 @@ enum SkAlphaType { }; static inline bool SkAlphaTypeIsOpaque(SkAlphaType at) { - SK_COMPILE_ASSERT(kIgnore_SkAlphaType < kOpaque_SkAlphaType, bad_alphatype_order); - SK_COMPILE_ASSERT(kPremul_SkAlphaType > kOpaque_SkAlphaType, bad_alphatype_order); - SK_COMPILE_ASSERT(kUnpremul_SkAlphaType > kOpaque_SkAlphaType, bad_alphatype_order); + return kOpaque_SkAlphaType == at; +} - return (unsigned)at <= kOpaque_SkAlphaType; +static inline bool SkAlphaTypeIsValid(unsigned value) { + return value <= kLastEnum_SkAlphaType; } /////////////////////////////////////////////////////////////////////////////// /** * Describes how to interpret the components of a pixel. + * + * kN32_SkColorType is an alias for whichever 32bit ARGB format is the "native" + * form for skia's blitters. Use this if you don't have a swizzle preference + * for 32bit pixels. */ enum SkColorType { + kUnknown_SkColorType, kAlpha_8_SkColorType, kRGB_565_SkColorType, kARGB_4444_SkColorType, kRGBA_8888_SkColorType, kBGRA_8888_SkColorType, kIndex_8_SkColorType, + kGray_8_SkColorType, + kRGBA_F16_SkColorType, + + kLastEnum_SkColorType = kRGBA_F16_SkColorType, - kLastEnum_SkColorType = kIndex_8_SkColorType, - -// FG-2014-09-26: [[ Bugfix 11968 ]] Disabled this check as it breaks PowerPC yet -// doesn't seem to accomplish anything useful. -//#if SK_PMCOLOR_BYTE_ORDER(B,G,R,A) - kPMColor_SkColorType = kBGRA_8888_SkColorType -//#elif SK_PMCOLOR_BYTE_ORDER(R,G,B,A) -// kPMColor_SkColorType = kRGBA_8888_SkColorType -//#else -//#error "SK_*32_SHFIT values must correspond to BGRA or RGBA byte order" -//#endif +#if SK_PMCOLOR_BYTE_ORDER(B,G,R,A) + kN32_SkColorType = kBGRA_8888_SkColorType, +#elif SK_PMCOLOR_BYTE_ORDER(R,G,B,A) + kN32_SkColorType = kRGBA_8888_SkColorType, +#else + #error "SK_*32_SHFIT values must correspond to BGRA or RGBA byte order" +#endif }; static int SkColorTypeBytesPerPixel(SkColorType ct) { static const uint8_t gSize[] = { + 0, // Unknown 1, // Alpha_8 2, // RGB_565 2, // ARGB_4444 4, // RGBA_8888 4, // BGRA_8888 1, // kIndex_8 + 1, // kGray_8 + 8, // kRGBA_F16 }; - SK_COMPILE_ASSERT(SK_ARRAY_COUNT(gSize) == (size_t)(kLastEnum_SkColorType + 1), - size_mismatch_with_SkColorType_enum); + static_assert(SK_ARRAY_COUNT(gSize) == (size_t)(kLastEnum_SkColorType + 1), + "size_mismatch_with_SkColorType_enum"); SkASSERT((size_t)ct < SK_ARRAY_COUNT(gSize)); return gSize[ct]; } +static int SkColorTypeShiftPerPixel(SkColorType ct) { + static const uint8_t gShift[] = { + 0, // Unknown + 0, // Alpha_8 + 1, // RGB_565 + 1, // ARGB_4444 + 2, // RGBA_8888 + 2, // BGRA_8888 + 0, // kIndex_8 + 0, // kGray_8 + 3, // kRGBA_F16 + }; + static_assert(SK_ARRAY_COUNT(gShift) == (size_t)(kLastEnum_SkColorType + 1), + "size_mismatch_with_SkColorType_enum"); + + SkASSERT((size_t)ct < SK_ARRAY_COUNT(gShift)); + return gShift[ct]; +} + +static inline size_t SkColorTypeMinRowBytes(SkColorType ct, int width) { + return width * SkColorTypeBytesPerPixel(ct); +} + +static inline bool SkColorTypeIsValid(unsigned value) { + return value <= kLastEnum_SkColorType; +} + +static inline size_t SkColorTypeComputeOffset(SkColorType ct, int x, int y, size_t rowBytes) { + if (kUnknown_SkColorType == ct) { + return 0; + } + return y * rowBytes + (x << SkColorTypeShiftPerPixel(ct)); +} + +/////////////////////////////////////////////////////////////////////////////// + +/** + * Return true if alphaType is supported by colorType. If there is a canonical + * alphaType for this colorType, return it in canonical. + */ +bool SkColorTypeValidateAlphaType(SkColorType colorType, SkAlphaType alphaType, + SkAlphaType* canonical = NULL); + /////////////////////////////////////////////////////////////////////////////// +/** + * Describes the color space a YUV pixel. + */ +enum SkYUVColorSpace { + /** Standard JPEG color space. */ + kJPEG_SkYUVColorSpace, + /** SDTV standard Rec. 601 color space. Uses "studio swing" [16, 235] color + range. See http://en.wikipedia.org/wiki/Rec._601 for details. */ + kRec601_SkYUVColorSpace, + /** HDTV standard Rec. 709 color space. Uses "studio swing" [16, 235] color + range. See http://en.wikipedia.org/wiki/Rec._709 for details. */ + kRec709_SkYUVColorSpace, + + kLastEnum_SkYUVColorSpace = kRec709_SkYUVColorSpace +}; + +/////////////////////////////////////////////////////////////////////////////// + +enum class SkDestinationSurfaceColorMode { + kLegacy, + kGammaAndColorSpaceAware, +}; + /** * Describe an image's dimensions and pixel type. + * Used for both src images and render-targets (surfaces). */ -struct SkImageInfo { - int fWidth; - int fHeight; - SkColorType fColorType; - SkAlphaType fAlphaType; +struct SK_API SkImageInfo { +public: + SkImageInfo() + : fColorSpace(nullptr) + , fWidth(0) + , fHeight(0) + , fColorType(kUnknown_SkColorType) + , fAlphaType(kUnknown_SkAlphaType) + {} + + static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at, + sk_sp cs = nullptr) { + return SkImageInfo(width, height, ct, at, std::move(cs)); + } + + /** + * Sets colortype to the native ARGB32 type. + */ + static SkImageInfo MakeN32(int width, int height, SkAlphaType at, + sk_sp cs = nullptr) { + return Make(width, height, kN32_SkColorType, at, cs); + } + + /** + * Create an ImageInfo marked as SRGB with N32 swizzle. + */ + static SkImageInfo MakeS32(int width, int height, SkAlphaType at); + + /** + * Sets colortype to the native ARGB32 type, and the alphatype to premul. + */ + static SkImageInfo MakeN32Premul(int width, int height, sk_sp cs = nullptr) { + return Make(width, height, kN32_SkColorType, kPremul_SkAlphaType, cs); + } + + static SkImageInfo MakeN32Premul(const SkISize& size) { + return MakeN32Premul(size.width(), size.height()); + } + + static SkImageInfo MakeA8(int width, int height) { + return Make(width, height, kAlpha_8_SkColorType, kPremul_SkAlphaType, nullptr); + } + + static SkImageInfo MakeUnknown(int width, int height) { + return Make(width, height, kUnknown_SkColorType, kUnknown_SkAlphaType, nullptr); + } + + static SkImageInfo MakeUnknown() { + return MakeUnknown(0, 0); + } + + int width() const { return fWidth; } + int height() const { return fHeight; } + SkColorType colorType() const { return fColorType; } + SkAlphaType alphaType() const { return fAlphaType; } + SkColorSpace* colorSpace() const { return fColorSpace.get(); } + + bool isEmpty() const { return fWidth <= 0 || fHeight <= 0; } bool isOpaque() const { return SkAlphaTypeIsOpaque(fAlphaType); } - int bytesPerPixel() const { - return SkColorTypeBytesPerPixel(fColorType); + SkISize dimensions() const { return SkISize::Make(fWidth, fHeight); } + SkIRect bounds() const { return SkIRect::MakeWH(fWidth, fHeight); } + + bool gammaCloseToSRGB() const { + return fColorSpace && fColorSpace->gammaCloseToSRGB(); + } + + /** + * Return a new ImageInfo with the same colortype and alphatype as this info, + * but with the specified width and height. + */ + SkImageInfo makeWH(int newWidth, int newHeight) const { + return Make(newWidth, newHeight, fColorType, fAlphaType, fColorSpace); + } + + SkImageInfo makeAlphaType(SkAlphaType newAlphaType) const { + return Make(fWidth, fHeight, fColorType, newAlphaType, fColorSpace); + } + + SkImageInfo makeColorType(SkColorType newColorType) const { + return Make(fWidth, fHeight, newColorType, fAlphaType, fColorSpace); + } + + SkImageInfo makeColorSpace(sk_sp cs) const { + return Make(fWidth, fHeight, fColorType, fAlphaType, std::move(cs)); + } + + int bytesPerPixel() const { return SkColorTypeBytesPerPixel(fColorType); } + + int shiftPerPixel() const { return SkColorTypeShiftPerPixel(fColorType); } + + uint64_t minRowBytes64() const { + return sk_64_mul(fWidth, this->bytesPerPixel()); } size_t minRowBytes() const { - return fWidth * this->bytesPerPixel(); + uint64_t minRowBytes = this->minRowBytes64(); + if (!sk_64_isS32(minRowBytes)) { + return 0; + } + return sk_64_asS32(minRowBytes); + } + + size_t computeOffset(int x, int y, size_t rowBytes) const { + SkASSERT((unsigned)x < (unsigned)fWidth); + SkASSERT((unsigned)y < (unsigned)fHeight); + return SkColorTypeComputeOffset(fColorType, x, y, rowBytes); } bool operator==(const SkImageInfo& other) const { - return 0 == memcmp(this, &other, sizeof(other)); + return fWidth == other.fWidth && fHeight == other.fHeight && + fColorType == other.fColorType && fAlphaType == other.fAlphaType && + SkColorSpace::Equals(fColorSpace.get(), other.fColorSpace.get()); } bool operator!=(const SkImageInfo& other) const { - return 0 != memcmp(this, &other, sizeof(other)); + return !(*this == other); } - void unflatten(SkFlattenableReadBuffer&); - void flatten(SkFlattenableWriteBuffer&) const; + void unflatten(SkReadBuffer&); + void flatten(SkWriteBuffer&) const; - size_t getSafeSize(size_t rowBytes) const { + int64_t getSafeSize64(size_t rowBytes) const { if (0 == fHeight) { return 0; } - return (fHeight - 1) * rowBytes + fWidth * this->bytesPerPixel(); + return sk_64_mul(fHeight - 1, rowBytes) + sk_64_mul(fWidth, this->bytesPerPixel()); + } + + size_t getSafeSize(size_t rowBytes) const { + int64_t size = this->getSafeSize64(rowBytes); + if (!sk_64_isS32(size)) { + return 0; + } + return sk_64_asS32(size); + } + + bool validRowBytes(size_t rowBytes) const { + uint64_t rb = sk_64_mul(fWidth, this->bytesPerPixel()); + return rowBytes >= rb; } + + void reset() { + fColorSpace = nullptr; + fWidth = 0; + fHeight = 0; + fColorType = kUnknown_SkColorType; + fAlphaType = kUnknown_SkAlphaType; + } + + SkDEBUGCODE(void validate() const;) + +private: + sk_sp fColorSpace; + int fWidth; + int fHeight; + SkColorType fColorType; + SkAlphaType fAlphaType; + + SkImageInfo(int width, int height, SkColorType ct, SkAlphaType at, sk_sp cs) + : fColorSpace(std::move(cs)) + , fWidth(width) + , fHeight(height) + , fColorType(ct) + , fAlphaType(at) + {} }; #endif diff --git a/libskia/include/core/SkInstCnt.h b/libskia/include/core/SkInstCnt.h deleted file mode 100644 index 89bbfa11..00000000 --- a/libskia/include/core/SkInstCnt.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright 2012 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - - -#ifndef SkInstCnt_DEFINED -#define SkInstCnt_DEFINED - -/* - * The instance counting system consists of three macros that create the - * instance counting machinery. A class is added to the system by adding: - * SK_DECLARE_INST_COUNT at the top of its declaration for derived classes - * SK_DECLARE_INST_COUNT_ROOT at the top of its declaration for a root class - * At the end of an application a call to all the "root" objects' - * CheckInstanceCount methods should be made - */ -#include "SkTypes.h" - -#if SK_ENABLE_INST_COUNT -#include "SkTArray.h" -#include "SkThread.h" - -extern bool gPrintInstCount; - -// The non-root classes just register themselves with their parent -#define SK_DECLARE_INST_COUNT(className) \ - SK_DECLARE_INST_COUNT_INTERNAL(className, \ - INHERITED::AddInstChild(CheckInstanceCount);) - -// The root classes registers a function to print out the memory stats when -// the app ends -#define SK_DECLARE_INST_COUNT_ROOT(className) \ - SK_DECLARE_INST_COUNT_INTERNAL(className, atexit(exitPrint);) - -#define SK_DECLARE_INST_COUNT_INTERNAL(className, initStep) \ - class SkInstanceCountHelper { \ - public: \ - typedef int (*PFCheckInstCnt)(int level, bool cleanUp); \ - SkInstanceCountHelper() { \ - static bool gInited; \ - if (!gInited) { \ - initStep \ - GetChildren() = new SkTArray; \ - gInited = true; \ - } \ - sk_atomic_inc(GetInstanceCountPtr()); \ - } \ - \ - SkInstanceCountHelper(const SkInstanceCountHelper&) { \ - sk_atomic_inc(GetInstanceCountPtr()); \ - } \ - \ - ~SkInstanceCountHelper() { \ - sk_atomic_dec(GetInstanceCountPtr()); \ - } \ - \ - static int32_t* GetInstanceCountPtr() { \ - static int32_t gInstanceCount; \ - return &gInstanceCount; \ - } \ - \ - static SkTArray*& GetChildren() { \ - static SkTArray* gChildren; \ - return gChildren; \ - } \ - \ - } fInstanceCountHelper; \ - \ - static int32_t GetInstanceCount() { \ - return *SkInstanceCountHelper::GetInstanceCountPtr(); \ - } \ - \ - static void exitPrint() { \ - CheckInstanceCount(0, true); \ - } \ - \ - static int CheckInstanceCount(int level = 0, bool cleanUp = false) { \ - if (gPrintInstCount && 0 != GetInstanceCount()) { \ - SkDebugf("%*c Leaked %s: %d\n", \ - 4*level, ' ', #className, \ - GetInstanceCount()); \ - } \ - if (NULL == SkInstanceCountHelper::GetChildren()) { \ - return GetInstanceCount(); \ - } \ - SkTArray* children = \ - SkInstanceCountHelper::GetChildren(); \ - int childCount = children->count(); \ - int count = GetInstanceCount(); \ - for (int i = 0; i < childCount; ++i) { \ - count -= (*(*children)[i])(level+1, cleanUp); \ - } \ - SkASSERT(count >= 0); \ - if (gPrintInstCount && childCount > 0 && count > 0) { \ - SkDebugf("%*c Leaked ???: %d\n", 4*(level + 1), ' ', count); \ - } \ - if (cleanUp) { \ - delete children; \ - SkInstanceCountHelper::GetChildren() = NULL; \ - } \ - return GetInstanceCount(); \ - } \ - \ - static void AddInstChild(int (*childCheckInstCnt)(int, bool)) { \ - if (CheckInstanceCount != childCheckInstCnt && \ - NULL != SkInstanceCountHelper::GetChildren()) { \ - SkInstanceCountHelper::GetChildren()->push_back(childCheckInstCnt); \ - } \ - } - -#else -// Typically SK_ENABLE_INST_COUNT=0. Make sure the class declares public typedef INHERITED by -// causing a compile-time error if the typedef is missing. This way SK_ENABLE_INST_COUNT=1 stays -// compiling. -#define SK_DECLARE_INST_COUNT(className) static void AddInstChild() { INHERITED::AddInstChild(); } -#define SK_DECLARE_INST_COUNT_ROOT(className) static void AddInstChild() { } -#endif - -// Following are deprecated. They are defined only for backwards API compatibility. -#define SK_DECLARE_INST_COUNT_TEMPLATE(className) SK_DECLARE_INST_COUNT(className) -#define SK_DEFINE_INST_COUNT(className) -#define SK_DEFINE_INST_COUNT_TEMPLATE(templateInfo, className) - -#endif // SkInstCnt_DEFINED diff --git a/libskia/include/core/SkLights.h b/libskia/include/core/SkLights.h new file mode 100644 index 00000000..954168de --- /dev/null +++ b/libskia/include/core/SkLights.h @@ -0,0 +1,199 @@ + +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkLights_DEFINED +#define SkLights_DEFINED + +#include "../private/SkTArray.h" +#include "SkPoint3.h" +#include "SkRefCnt.h" + +class SkReadBuffer; +class SkWriteBuffer; +class SkImage; + +class SK_API SkLights : public SkRefCnt { +public: + class Light { + public: + enum LightType { + kDirectional_LightType, + kPoint_LightType + }; + + Light(const Light& other) + : fType(other.fType) + , fColor(other.fColor) + , fDirOrPos(other.fDirOrPos) + , fIntensity(other.fIntensity) + , fShadowMap(other.fShadowMap) + , fIsRadial(other.fIsRadial) { + } + + Light(Light&& other) + : fType(other.fType) + , fColor(other.fColor) + , fDirOrPos(other.fDirOrPos) + , fIntensity(other.fIntensity) + , fShadowMap(std::move(other.fShadowMap)) + , fIsRadial(other.fIsRadial) { + } + + static Light MakeDirectional(const SkColor3f& color, const SkVector3& dir, + bool isRadial = false) { + Light light(kDirectional_LightType, color, dir, isRadial); + if (!light.fDirOrPos.normalize()) { + light.fDirOrPos.set(0.0f, 0.0f, 1.0f); + } + return light; + } + + static Light MakePoint(const SkColor3f& color, const SkPoint3& pos, SkScalar intensity, + bool isRadial = false) { + return Light(kPoint_LightType, color, pos, intensity, isRadial); + } + + LightType type() const { return fType; } + const SkColor3f& color() const { return fColor; } + const SkVector3& dir() const { + SkASSERT(kDirectional_LightType == fType); + return fDirOrPos; + } + const SkPoint3& pos() const { + SkASSERT(kPoint_LightType == fType); + return fDirOrPos; + } + SkScalar intensity() const { + SkASSERT(kPoint_LightType == fType); + return fIntensity; + } + + void setShadowMap(sk_sp shadowMap) { + fShadowMap = std::move(shadowMap); + } + + SkImage* getShadowMap() const { + return fShadowMap.get(); + } + + bool isRadial() const { return fIsRadial; } + + Light& operator= (const Light& b) { + if (this == &b) { + return *this; + } + + fColor = b.fColor; + fType = b.fType; + fDirOrPos = b.fDirOrPos; + fIntensity = b.fIntensity; + fShadowMap = b.fShadowMap; + fIsRadial = b.fIsRadial; + return *this; + } + + bool operator== (const Light& b) { + if (this == &b) { + return true; + } + + return (fColor == b.fColor) && + (fType == b.fType) && + (fDirOrPos == b.fDirOrPos) && + (fShadowMap == b.fShadowMap) && + (fIntensity == b.fIntensity) && + (fIsRadial == b.fIsRadial); + } + + bool operator!= (const Light& b) { return !(this->operator==(b)); } + + private: + LightType fType; + SkColor3f fColor; // linear (unpremul) color. Range is 0..1 in each channel. + + SkVector3 fDirOrPos; // For directional lights, holds the direction towards the + // light (+Z is out of the screen). + // If degenerate, it will be replaced with (0, 0, 1). + // For point lights, holds location of point light + + SkScalar fIntensity; // For point lights, dictates the light intensity. + // Simply a multiplier to the final light output value. + sk_sp fShadowMap; + bool fIsRadial; // Whether the light is radial or not. Radial lights will + // cast shadows and lights radially outwards. + + Light(LightType type, const SkColor3f& color, const SkVector3& dirOrPos, + SkScalar intensity = 0.0f, bool isRadial = false) { + fType = type; + fColor = color; + fDirOrPos = dirOrPos; + fIntensity = intensity; + fIsRadial = isRadial; + } + }; + + class Builder { + public: + Builder() : fLights(new SkLights) {} + + void add(const Light& light) { + if (fLights) { + fLights->fLights.push_back(light); + } + } + + void add(Light&& light) { + if (fLights) { + fLights->fLights.push_back(std::move(light)); + } + } + + void setAmbientLightColor(const SkColor3f& color) { + if (fLights) { + fLights->fAmbientLightColor = color; + } + } + + sk_sp finish() { + return std::move(fLights); + } + + private: + sk_sp fLights; + }; + + int numLights() const { + return fLights.count(); + } + + const Light& light(int index) const { + return fLights[index]; + } + + Light& light(int index) { + return fLights[index]; + } + + const SkColor3f& ambientLightColor() const { + return fAmbientLightColor; + } + + static sk_sp MakeFromBuffer(SkReadBuffer& buf); + + void flatten(SkWriteBuffer& buf) const; + +private: + SkLights() { + fAmbientLightColor.set(0.0f, 0.0f, 0.0f); + } + SkTArray fLights; + SkColor3f fAmbientLightColor; + typedef SkRefCnt INHERITED; +}; + +#endif diff --git a/libskia/include/core/SkMallocPixelRef.h b/libskia/include/core/SkMallocPixelRef.h index c40afc43..ab337b92 100644 --- a/libskia/include/core/SkMallocPixelRef.h +++ b/libskia/include/core/SkMallocPixelRef.h @@ -1,4 +1,3 @@ - /* * Copyright 2008 The Android Open Source Project * @@ -15,7 +14,7 @@ /** We explicitly use the same allocator for our pixels that SkMask does, so that we can freely assign memory allocated by one class to the other. */ -class SkMallocPixelRef : public SkPixelRef { +class SK_API SkMallocPixelRef : public SkPixelRef { public: /** * Return a new SkMallocPixelRef with the provided pixel storage, rowBytes, @@ -43,6 +42,12 @@ class SkMallocPixelRef : public SkPixelRef { static SkMallocPixelRef* NewAllocate(const SkImageInfo& info, size_t rowBytes, SkColorTable*); + /** + * Identical to NewAllocate, except all pixel bytes are zeroed. + */ + static SkMallocPixelRef* NewZeroed(const SkImageInfo& info, + size_t rowBytes, SkColorTable*); + /** * Return a new SkMallocPixelRef with the provided pixel storage, * rowBytes, and optional colortable. On destruction, ReleaseProc @@ -50,6 +55,11 @@ class SkMallocPixelRef : public SkPixelRef { * * This pixelref will ref() the specified colortable (if not NULL). * + * If ReleaseProc is NULL, the pixels will never be released. This + * can be useful if the pixels were stack allocated. However, such an + * SkMallocPixelRef must not live beyond its pixels (e.g. by copying + * an SkBitmap pointing to it, or drawing to an SkPicture). + * * Returns NULL on failure. */ typedef void (*ReleaseProc)(void* addr, void* context); @@ -64,9 +74,6 @@ class SkMallocPixelRef : public SkPixelRef { * The SkData will be ref()ed and on destruction of the PielRef, * the SkData will be unref()ed. * - * @param offset (in bytes) into the provided SkData that the - * first pixel is located at. - * * This pixelref will ref() the specified colortable (if not NULL). * * Returns NULL on failure. @@ -74,26 +81,37 @@ class SkMallocPixelRef : public SkPixelRef { static SkMallocPixelRef* NewWithData(const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable, - SkData* data, - size_t offset = 0); + SkData* data); void* getAddr() const { return fStorage; } - SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkMallocPixelRef) + class PRFactory : public SkPixelRefFactory { + public: + SkPixelRef* create(const SkImageInfo&, size_t rowBytes, SkColorTable*) override; + }; + + class ZeroedPRFactory : public SkPixelRefFactory { + public: + SkPixelRef* create(const SkImageInfo&, size_t rowBytes, SkColorTable*) override; + }; protected: // The ownPixels version of this constructor is deprecated. SkMallocPixelRef(const SkImageInfo&, void* addr, size_t rb, SkColorTable*, bool ownPixels); - SkMallocPixelRef(SkFlattenableReadBuffer& buffer); virtual ~SkMallocPixelRef(); - virtual bool onNewLockPixels(LockRec*) SK_OVERRIDE; - virtual void onUnlockPixels() SK_OVERRIDE; - virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE; - virtual size_t getAllocatedSizeInBytes() const SK_OVERRIDE; + bool onNewLockPixels(LockRec*) override; + void onUnlockPixels() override; + size_t getAllocatedSizeInBytes() const override; private: + // Uses alloc to implement NewAllocate or NewZeroed. + static SkMallocPixelRef* NewUsing(void*(*alloc)(size_t), + const SkImageInfo&, + size_t rowBytes, + SkColorTable*); + void* fStorage; SkColorTable* fCTable; size_t fRB; diff --git a/libskia/include/core/SkMask.h b/libskia/include/core/SkMask.h index 5cfef970..a6d56064 100644 --- a/libskia/include/core/SkMask.h +++ b/libskia/include/core/SkMask.h @@ -17,17 +17,18 @@ the 3-channel 3D format. These are passed to SkMaskFilter objects. */ struct SkMask { + SkMask() : fImage(nullptr) {} + enum Format { kBW_Format, //!< 1bit per pixel mask (e.g. monochrome) kA8_Format, //!< 8bits per pixel mask (e.g. antialiasing) k3D_Format, //!< 3 8bit per pixl planes: alpha, mul, add kARGB32_Format, //!< SkPMColor kLCD16_Format, //!< 565 alpha for r/g/b - kLCD32_Format //!< 888 alpha for r/g/b }; enum { - kCountMaskFormats = kLCD32_Format + 1 + kCountMaskFormats = kLCD16_Format + 1 }; uint8_t* fImage; @@ -86,26 +87,13 @@ struct SkMask { return row + (x - fBounds.fLeft); } - /** - * Return the address of the specified 32bit mask. In the debug build, - * this asserts that the mask's format is kLCD32_Format, and that (x,y) - * are contained in the mask's fBounds. - */ - uint32_t* getAddrLCD32(int x, int y) const { - SkASSERT(kLCD32_Format == fFormat); - SkASSERT(fBounds.contains(x, y)); - SkASSERT(fImage != NULL); - uint32_t* row = (uint32_t*)(fImage + (y - fBounds.fTop) * fRowBytes); - return row + (x - fBounds.fLeft); - } - /** * Return the address of the specified 32bit mask. In the debug build, * this asserts that the mask's format is 32bits, and that (x,y) * are contained in the mask's fBounds. */ uint32_t* getAddr32(int x, int y) const { - SkASSERT(kLCD32_Format == fFormat || kARGB32_Format == fFormat); + SkASSERT(kARGB32_Format == fFormat); SkASSERT(fBounds.contains(x, y)); SkASSERT(fImage != NULL); uint32_t* row = (uint32_t*)(fImage + (y - fBounds.fTop) * fRowBytes); @@ -116,7 +104,7 @@ struct SkMask { * Returns the address of the specified pixel, computing the pixel-size * at runtime based on the mask format. This will be slightly slower than * using one of the routines where the format is implied by the name - * e.g. getAddr8 or getAddrLCD32. + * e.g. getAddr8 or getAddr32. * * x,y must be contained by the mask's bounds (this is asserted in the * debug build, but not checked in the release build.) diff --git a/libskia/include/core/SkMaskFilter.h b/libskia/include/core/SkMaskFilter.h index f4448ddd..2d004775 100644 --- a/libskia/include/core/SkMaskFilter.h +++ b/libskia/include/core/SkMaskFilter.h @@ -10,14 +10,23 @@ #ifndef SkMaskFilter_DEFINED #define SkMaskFilter_DEFINED +#include "SkBlurTypes.h" #include "SkFlattenable.h" #include "SkMask.h" #include "SkPaint.h" +#include "SkStrokeRec.h" +class GrClip; class GrContext; +class GrRenderTargetContext; +class GrPaint; +class GrFragmentProcessor; +class GrRenderTarget; +class GrTexture; +class GrTextureProvider; class SkBitmap; class SkBlitter; -class SkBounder; +class SkCachedData; class SkMatrix; class SkPath; class SkRasterClip; @@ -36,10 +45,6 @@ class SkRRect; */ class SK_API SkMaskFilter : public SkFlattenable { public: - SK_DECLARE_INST_COUNT(SkMaskFilter) - - SkMaskFilter() {} - /** Returns the format of the resulting mask that this subclass will return when its filterMask() method is called. */ @@ -63,53 +68,83 @@ class SK_API SkMaskFilter : public SkFlattenable { #if SK_SUPPORT_GPU /** - * Returns true if the filter can be expressed a single-pass - * GrEffect, used to process this filter on the GPU, or false if - * not. + * Returns true if the filter can be expressed a single-pass GrProcessor without requiring an + * explicit input mask. Per-pixel, the effect receives the incoming mask's coverage as + * the input color and outputs the filtered covereage value. This means that each pixel's + * filtered coverage must only depend on the unfiltered mask value for that pixel and not on + * surrounding values. * - * If effect is non-NULL, a new GrEffect instance is stored - * in it. The caller assumes ownership of the stage, and it is up to the - * caller to unref it. + * If effect is non-NULL, a new GrProcessor instance is stored in it. The caller assumes + * ownership of the effect and must unref it. */ - virtual bool asNewEffect(GrEffectRef** effect, GrTexture*) const; + virtual bool asFragmentProcessor(GrFragmentProcessor**, GrTexture*, const SkMatrix& ctm) const; /** - * Returns true if the filter can be processed on the GPU. This is most - * often used for multi-pass effects, where intermediate results must be - * rendered to textures. For single-pass effects, use asNewEffect(). + * If asFragmentProcessor() fails the filter may be implemented on the GPU by a subclass + * overriding filterMaskGPU (declared below). That code path requires constructing a + * src mask as input. Since that is a potentially expensive operation, the subclass must also + * override this function to indicate whether filterTextureMaskGPU would succeeed if the mask + * were to be created. + * + * 'maskRect' returns the device space portion of the mask that the filter needs. The mask + * passed into 'filterMaskGPU' should have the same extent as 'maskRect' but be + * translated to the upper-left corner of the mask (i.e., (maskRect.fLeft, maskRect.fTop) + * appears at (0, 0) in the mask). * - * 'maskRect' returns the device space portion of the mask the the filter - * needs. The mask passed into 'filterMaskGPU' should have the same extent - * as 'maskRect' but be translated to the upper-left corner of the mask - * (i.e., (maskRect.fLeft, maskRect.fTop) appears at (0, 0) in the mask). + * Logically, how this works is: + * canFilterMaskGPU is called + * if (it returns true) + * the returned mask rect is used for quick rejecting + * either directFilterMaskGPU or directFilterRRectMaskGPU is then called + * if (neither of them handle the blur) + * the mask rect is used to generate the mask + * filterMaskGPU is called to filter the mask + * + * TODO: this should work as: + * if (canFilterMaskGPU(devShape, ...)) // rect, rrect, drrect, path + * filterMaskGPU(devShape, ...) + * this would hide the RRect special case and the mask generation */ - virtual bool canFilterMaskGPU(const SkRect& devBounds, + virtual bool canFilterMaskGPU(const SkRRect& devRRect, const SkIRect& clipBounds, const SkMatrix& ctm, SkRect* maskRect) const; /** - * Perform this mask filter on the GPU. This is most often used for - * multi-pass effects, where intermediate results must be rendered to - * textures. For single-pass effects, use asNewEffect(). 'src' is the - * source image for processing, as a texture-backed bitmap. 'result' is - * the destination bitmap, which should contain a texture-backed pixelref - * on success. 'maskRect' should be the rect returned from canFilterMaskGPU. + * Try to directly render the mask filter into the target. Returns + * true if drawing was successful. + */ + virtual bool directFilterMaskGPU(GrTextureProvider* texProvider, + GrRenderTargetContext* renderTargetContext, + GrPaint* grp, + const GrClip&, + const SkMatrix& viewMatrix, + const SkStrokeRec& strokeRec, + const SkPath& path) const; + /** + * Try to directly render a rounded rect mask filter into the target. Returns + * true if drawing was successful. */ - bool filterMaskGPU(GrContext* context, - const SkBitmap& src, - const SkRect& maskRect, - SkBitmap* result) const; + virtual bool directFilterRRectMaskGPU(GrContext*, + GrRenderTargetContext* renderTargetContext, + GrPaint* grp, + const GrClip&, + const SkMatrix& viewMatrix, + const SkStrokeRec& strokeRec, + const SkRRect& rrect, + const SkRRect& devRRect) const; /** - * This flavor of 'filterMaskGPU' provides a more direct means of accessing - * the filtering capabilities. Setting 'canOverwriteSrc' can allow some - * filters to skip the allocation of an additional texture. + * This function is used to implement filters that require an explicit src mask. It should only + * be called if canFilterMaskGPU returned true and the maskRect param should be the output from + * that call. + * Implementations are free to get the GrContext from the src texture in order to create + * additional textures and perform multiple passes. */ virtual bool filterMaskGPU(GrTexture* src, - const SkRect& maskRect, - GrTexture** result, - bool canOverwriteSrc) const; + const SkMatrix& ctm, + const SkIRect& maskRect, + GrTexture** result) const; #endif /** @@ -125,12 +160,23 @@ class SK_API SkMaskFilter : public SkFlattenable { */ virtual void computeFastBounds(const SkRect& src, SkRect* dest) const; - SkDEVCODE(virtual void toString(SkString* str) const = 0;) + struct BlurRec { + SkScalar fSigma; + SkBlurStyle fStyle; + SkBlurQuality fQuality; + }; + /** + * If this filter can be represented by a BlurRec, return true and (if not null) fill in the + * provided BlurRec parameter. If this effect cannot be represented as a BlurRec, return false + * and ignore the BlurRec parameter. + */ + virtual bool asABlur(BlurRec*) const; + + SK_TO_STRING_PUREVIRT() SK_DEFINE_FLATTENABLE_TYPE(SkMaskFilter) protected: - // empty for now, but lets get our subclass to remember to init us for the future - SkMaskFilter(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {} + SkMaskFilter() {} enum FilterReturn { kFalse_FilterReturn, @@ -138,10 +184,15 @@ class SK_API SkMaskFilter : public SkFlattenable { kUnimplemented_FilterReturn }; - struct NinePatch { + class NinePatch : ::SkNoncopyable { + public: + NinePatch() : fCache(nullptr) { } + ~NinePatch(); + SkMask fMask; // fBounds must have [0,0] in its top-left SkIRect fOuterRect; // width/height must be >= fMask.fBounds' SkIPoint fCenter; // identifies center row/col for stretching + SkCachedData* fCache; }; /** @@ -178,17 +229,15 @@ class SK_API SkMaskFilter : public SkFlattenable { to render that mask. Returns false if filterMask() returned false. This method is not exported to java. */ - bool filterPath(const SkPath& devPath, const SkMatrix& devMatrix, - const SkRasterClip&, SkBounder*, SkBlitter* blitter, - SkPaint::Style style) const; + bool filterPath(const SkPath& devPath, const SkMatrix& ctm, const SkRasterClip&, SkBlitter*, + SkStrokeRec::InitStyle) const; /** Helper method that, given a roundRect in device space, will rasterize it into a kA8_Format mask and then call filterMask(). If this returns true, the specified blitter will be called to render that mask. Returns false if filterMask() returned false. */ - bool filterRRect(const SkRRect& devRRect, const SkMatrix& devMatrix, - const SkRasterClip&, SkBounder*, SkBlitter* blitter, - SkPaint::Style style) const; + bool filterRRect(const SkRRect& devRRect, const SkMatrix& ctm, const SkRasterClip&, + SkBlitter*) const; typedef SkFlattenable INHERITED; }; diff --git a/libskia/include/core/SkMath.h b/libskia/include/core/SkMath.h index ba6223ed..6e252306 100644 --- a/libskia/include/core/SkMath.h +++ b/libskia/include/core/SkMath.h @@ -12,29 +12,6 @@ #include "SkTypes.h" -/** - * Computes numer1 * numer2 / denom in full 64 intermediate precision. - * It is an error for denom to be 0. There is no special handling if - * the result overflows 32bits. - */ -int32_t SkMulDiv(int32_t numer1, int32_t numer2, int32_t denom); - -/** - * Computes (numer1 << shift) / denom in full 64 intermediate precision. - * It is an error for denom to be 0. There is no special handling if - * the result overflows 32bits. - */ -int32_t SkDivBits(int32_t numer, int32_t denom, int shift); - -/** - * Return the integer square root of value, with a bias of bitBias - */ -int32_t SkSqrtBits(int32_t value, int bitBias); - -/** Return the integer square root of n, treated as a SkFixed (16.16) - */ -#define SkSqrt32(n) SkSqrtBits(n, 15) - // 64bit -> 32bit utilities /** @@ -63,31 +40,26 @@ static inline int64_t sk_64_mul(int64_t a, int64_t b) { /////////////////////////////////////////////////////////////////////////////// -//! Returns the number of leading zero bits (0...32) -int SkCLZ_portable(uint32_t); - -#ifndef SkCLZ - #if defined(_MSC_VER) && _MSC_VER >= 1400 - #include - - static inline int SkCLZ(uint32_t mask) { - if (mask) { - DWORD index; - _BitScanReverse(&index, mask); - return index ^ 0x1F; - } else { - return 32; - } - } - #elif defined(SK_CPU_ARM) || defined(__GNUC__) || defined(__clang__) - static inline int SkCLZ(uint32_t mask) { - // __builtin_clz(0) is undefined, so we have to detect that case. - return mask ? __builtin_clz(mask) : 32; - } - #else - #define SkCLZ(x) SkCLZ_portable(x) - #endif -#endif +/** + * Computes numer1 * numer2 / denom in full 64 intermediate precision. + * It is an error for denom to be 0. There is no special handling if + * the result overflows 32bits. + */ +static inline int32_t SkMulDiv(int32_t numer1, int32_t numer2, int32_t denom) { + SkASSERT(denom); + + int64_t tmp = sk_64_mul(numer1, numer2) / denom; + return sk_64_asS32(tmp); +} + +/** + * Return the integer square root of value, with a bias of bitBias + */ +int32_t SkSqrtBits(int32_t value, int bitBias); + +/** Return the integer square root of n, treated as a SkFixed (16.16) + */ +#define SkSqrt32(n) SkSqrtBits(n, 15) /** * Returns (value < 0 ? 0 : value) efficiently (i.e. no compares or branches) @@ -114,68 +86,16 @@ static inline int SkClampMax(int value, int max) { return value; } -/** - * Returns the smallest power-of-2 that is >= the specified value. If value - * is already a power of 2, then it is returned unchanged. It is undefined - * if value is <= 0. - */ -static inline int SkNextPow2(int value) { - SkASSERT(value > 0); - return 1 << (32 - SkCLZ(value - 1)); -} - -/** - * Returns the log2 of the specified value, were that value to be rounded up - * to the next power of 2. It is undefined to pass 0. Examples: - * SkNextLog2(1) -> 0 - * SkNextLog2(2) -> 1 - * SkNextLog2(3) -> 2 - * SkNextLog2(4) -> 2 - * SkNextLog2(5) -> 3 - */ -static inline int SkNextLog2(uint32_t value) { - SkASSERT(value != 0); - return 32 - SkCLZ(value - 1); -} - /** * Returns true if value is a power of 2. Does not explicitly check for * value <= 0. */ -static inline bool SkIsPow2(int value) { +template constexpr inline bool SkIsPow2(T value) { return (value & (value - 1)) == 0; } /////////////////////////////////////////////////////////////////////////////// -/** - * SkMulS16(a, b) multiplies a * b, but requires that a and b are both int16_t. - * With this requirement, we can generate faster instructions on some - * architectures. - */ -#ifdef SK_ARM_HAS_EDSP - static inline int32_t SkMulS16(S16CPU x, S16CPU y) { - SkASSERT((int16_t)x == x); - SkASSERT((int16_t)y == y); - int32_t product; - asm("smulbb %0, %1, %2 \n" - : "=r"(product) - : "r"(x), "r"(y) - ); - return product; - } -#else - #ifdef SK_DEBUG - static inline int32_t SkMulS16(S16CPU x, S16CPU y) { - SkASSERT((int16_t)x == x); - SkASSERT((int16_t)y == y); - return x * y; - } - #else - #define SkMulS16(x, y) ((x) * (y)) - #endif -#endif - /** * Return a*b/((1 << shift) - 1), rounding any fractional bits. * Only valid if a and b are unsigned and <= 32767 and shift is > 0 and <= 8 @@ -184,7 +104,7 @@ static inline unsigned SkMul16ShiftRound(U16CPU a, U16CPU b, int shift) { SkASSERT(a <= 32767); SkASSERT(b <= 32767); SkASSERT(shift > 0 && shift <= 8); - unsigned prod = SkMulS16(a, b) + (1 << (shift - 1)); + unsigned prod = a*b + (1 << (shift - 1)); return (prod + (prod >> shift)) >> shift; } @@ -195,7 +115,7 @@ static inline unsigned SkMul16ShiftRound(U16CPU a, U16CPU b, int shift) { static inline U8CPU SkMulDiv255Round(U16CPU a, U16CPU b) { SkASSERT(a <= 32767); SkASSERT(b <= 32767); - unsigned prod = SkMulS16(a, b) + 128; + unsigned prod = a*b + 128; return (prod + (prod >> 8)) >> 8; } @@ -204,7 +124,7 @@ static inline U8CPU SkMulDiv255Round(U16CPU a, U16CPU b) { */ template inline void SkTDivMod(In numer, In denom, Out* div, Out* mod) { -#ifdef SK_CPU_ARM +#ifdef SK_CPU_ARM32 // If we wrote this as in the else branch, GCC won't fuse the two into one // divmod call, but rather a div call followed by a divmod. Silly! This // version is just as fast as calling __aeabi_[u]idivmod manually, but with @@ -218,7 +138,7 @@ inline void SkTDivMod(In numer, In denom, Out* div, Out* mod) { // On x86 this will just be a single idiv. *div = static_cast(numer/denom); *mod = static_cast(numer%denom); -#endif // SK_CPU_ARM +#endif } #endif diff --git a/libskia/include/core/SkMatrix.h b/libskia/include/core/SkMatrix.h index 9bbbc174..f565a537 100644 --- a/libskia/include/core/SkMatrix.h +++ b/libskia/include/core/SkMatrix.h @@ -12,13 +12,9 @@ #include "SkRect.h" +struct SkRSXform; class SkString; -// TODO: can we remove these 3 (need to check chrome/android) -typedef SkScalar SkPersp; -#define SkScalarToPersp(x) (x) -#define SkPerspToScalar(x) (x) - /** \class SkMatrix The SkMatrix class holds a 3x3 matrix for transforming coordinates. @@ -26,8 +22,27 @@ typedef SkScalar SkPersp; using either reset() - to construct an identity matrix, or one of the set functions (e.g. setTranslate, setRotate, etc.). */ +SK_BEGIN_REQUIRE_DENSE class SK_API SkMatrix { public: + static SkMatrix SK_WARN_UNUSED_RESULT MakeScale(SkScalar sx, SkScalar sy) { + SkMatrix m; + m.setScale(sx, sy); + return m; + } + + static SkMatrix SK_WARN_UNUSED_RESULT MakeScale(SkScalar scale) { + SkMatrix m; + m.setScale(scale, scale); + return m; + } + + static SkMatrix SK_WARN_UNUSED_RESULT MakeTrans(SkScalar dx, SkScalar dy) { + SkMatrix m; + m.setTranslate(dx, dy); + return m; + } + /** Enum of bit fields for the mask return by getType(). Use this to identify the complexity of the matrix. */ @@ -59,9 +74,13 @@ class SK_API SkMatrix { return this->getType() == 0; } + bool isScaleTranslate() const { + return !(this->getType() & ~(kScale_Mask | kTranslate_Mask)); + } + /** Returns true if will map a rectangle to another rectangle. This can be true if the matrix is identity, scale-only, or rotates a multiple of - 90 degrees. + 90 degrees, or mirrors in x or y. */ bool rectStaysRect() const { if (fTypeMask & kUnknown_Mask) { @@ -80,12 +99,12 @@ class SK_API SkMatrix { kPerspective_Mask); } - /** Returns true if the matrix contains only translation, rotation or uniform scale + /** Returns true if the matrix contains only translation, rotation/reflection or uniform scale Returns false if other transformation types are included or is degenerate */ bool isSimilarity(SkScalar tol = SK_ScalarNearlyZero) const; - /** Returns true if the matrix contains only translation, rotation or scale + /** Returns true if the matrix contains only translation, rotation/reflection or scale (non-uniform scale is allowed). Returns false if other transformation types are included or is degenerate */ @@ -131,8 +150,8 @@ class SK_API SkMatrix { SkScalar getSkewX() const { return fMat[kMSkewX]; } SkScalar getTranslateX() const { return fMat[kMTransX]; } SkScalar getTranslateY() const { return fMat[kMTransY]; } - SkPersp getPerspX() const { return fMat[kMPersp0]; } - SkPersp getPerspY() const { return fMat[kMPersp1]; } + SkScalar getPerspX() const { return fMat[kMPersp0]; } + SkScalar getPerspY() const { return fMat[kMPersp1]; } SkScalar& operator[](int index) { SkASSERT((unsigned)index < 9); @@ -152,12 +171,12 @@ class SK_API SkMatrix { void setSkewX(SkScalar v) { this->set(kMSkewX, v); } void setTranslateX(SkScalar v) { this->set(kMTransX, v); } void setTranslateY(SkScalar v) { this->set(kMTransY, v); } - void setPerspX(SkPersp v) { this->set(kMPersp0, v); } - void setPerspY(SkPersp v) { this->set(kMPersp1, v); } + void setPerspX(SkScalar v) { this->set(kMPersp0, v); } + void setPerspY(SkScalar v) { this->set(kMPersp1, v); } - void setAll(SkScalar scaleX, SkScalar skewX, SkScalar transX, - SkScalar skewY, SkScalar scaleY, SkScalar transY, - SkPersp persp0, SkPersp persp1, SkPersp persp2) { + void setAll(SkScalar scaleX, SkScalar skewX, SkScalar transX, + SkScalar skewY, SkScalar scaleY, SkScalar transY, + SkScalar persp0, SkScalar persp1, SkScalar persp2) { fMat[kMScaleX] = scaleX; fMat[kMSkewX] = skewX; fMat[kMTransX] = transX; @@ -170,6 +189,23 @@ class SK_API SkMatrix { this->setTypeMask(kUnknown_Mask); } + /** + * Copy the 9 scalars for this matrix into buffer, in the same order as the kMScaleX + * enum... scalex, skewx, transx, skewy, scaley, transy, persp0, persp1, persp2 + */ + void get9(SkScalar buffer[9]) const { + memcpy(buffer, fMat, 9 * sizeof(SkScalar)); + } + + /** + * Set this matrix to the 9 scalars from the buffer, in the same order as the kMScaleX + * enum... scalex, skewx, transx, skewy, scaley, transy, persp0, persp1, persp2 + * + * Note: calling set9 followed by get9 may not return the exact same values. Since the matrix + * is used to map non-homogeneous coordinates, it is free to rescale the 9 values as needed. + */ + void set9(const SkScalar buffer[9]); + /** Set the matrix to identity */ void reset(); @@ -210,6 +246,9 @@ class SK_API SkMatrix { /** Set the matrix to rotate by the specified sine and cosine values. */ void setSinCos(SkScalar sinValue, SkScalar cosValue); + + SkMatrix& setRSXform(const SkRSXform&); + /** Set the matrix to skew by sx and sy, with a pivot point at (px, py). The pivot point is the coordinate that should remain unchanged by the specified transformation. @@ -218,57 +257,57 @@ class SK_API SkMatrix { /** Set the matrix to skew by sx and sy. */ void setSkew(SkScalar kx, SkScalar ky); - /** Set the matrix to the concatenation of the two specified matrices, - returning true if the the result can be represented. Either of the - two matrices may also be the target matrix. *this = a * b; + /** Set the matrix to the concatenation of the two specified matrices. + Either of the two matrices may also be the target matrix. + *this = a * b; */ - bool setConcat(const SkMatrix& a, const SkMatrix& b); + void setConcat(const SkMatrix& a, const SkMatrix& b); /** Preconcats the matrix with the specified translation. M' = M * T(dx, dy) */ - bool preTranslate(SkScalar dx, SkScalar dy); + void preTranslate(SkScalar dx, SkScalar dy); /** Preconcats the matrix with the specified scale. M' = M * S(sx, sy, px, py) */ - bool preScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py); + void preScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py); /** Preconcats the matrix with the specified scale. M' = M * S(sx, sy) */ - bool preScale(SkScalar sx, SkScalar sy); + void preScale(SkScalar sx, SkScalar sy); /** Preconcats the matrix with the specified rotation. M' = M * R(degrees, px, py) */ - bool preRotate(SkScalar degrees, SkScalar px, SkScalar py); + void preRotate(SkScalar degrees, SkScalar px, SkScalar py); /** Preconcats the matrix with the specified rotation. M' = M * R(degrees) */ - bool preRotate(SkScalar degrees); + void preRotate(SkScalar degrees); /** Preconcats the matrix with the specified skew. M' = M * K(kx, ky, px, py) */ - bool preSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py); + void preSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py); /** Preconcats the matrix with the specified skew. M' = M * K(kx, ky) */ - bool preSkew(SkScalar kx, SkScalar ky); + void preSkew(SkScalar kx, SkScalar ky); /** Preconcats the matrix with the specified matrix. M' = M * other */ - bool preConcat(const SkMatrix& other); + void preConcat(const SkMatrix& other); /** Postconcats the matrix with the specified translation. M' = T(dx, dy) * M */ - bool postTranslate(SkScalar dx, SkScalar dy); + void postTranslate(SkScalar dx, SkScalar dy); /** Postconcats the matrix with the specified scale. M' = S(sx, sy, px, py) * M */ - bool postScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py); + void postScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py); /** Postconcats the matrix with the specified scale. M' = S(sx, sy) * M */ - bool postScale(SkScalar sx, SkScalar sy); + void postScale(SkScalar sx, SkScalar sy); /** Postconcats the matrix by dividing it by the specified integers. M' = S(1/divx, 1/divy, 0, 0) * M */ @@ -276,23 +315,23 @@ class SK_API SkMatrix { /** Postconcats the matrix with the specified rotation. M' = R(degrees, px, py) * M */ - bool postRotate(SkScalar degrees, SkScalar px, SkScalar py); + void postRotate(SkScalar degrees, SkScalar px, SkScalar py); /** Postconcats the matrix with the specified rotation. M' = R(degrees) * M */ - bool postRotate(SkScalar degrees); + void postRotate(SkScalar degrees); /** Postconcats the matrix with the specified skew. M' = K(kx, ky, px, py) * M */ - bool postSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py); + void postSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py); /** Postconcats the matrix with the specified skew. M' = K(kx, ky) * M */ - bool postSkew(SkScalar kx, SkScalar ky); + void postSkew(SkScalar kx, SkScalar ky); /** Postconcats the matrix with the specified matrix. M' = other * M */ - bool postConcat(const SkMatrix& other); + void postConcat(const SkMatrix& other); enum ScaleToFit { /** @@ -331,6 +370,11 @@ class SK_API SkMatrix { @return true if the matrix can be represented by the rectangle mapping. */ bool setRectToRect(const SkRect& src, const SkRect& dst, ScaleToFit stf); + static SkMatrix MakeRectToRect(const SkRect& src, const SkRect& dst, ScaleToFit stf) { + SkMatrix m; + m.setRectToRect(src, dst, stf); + return m; + } /** Set the matrix such that the specified src points would map to the specified dst points. count must be within [0..4]. @@ -348,7 +392,7 @@ class SK_API SkMatrix { bool SK_WARN_UNUSED_RESULT invert(SkMatrix* inverse) const { // Allow the trivial case to be inlined. if (this->isIdentity()) { - if (NULL != inverse) { + if (inverse) { inverse->reset(); } return true; @@ -368,7 +412,12 @@ class SK_API SkMatrix { and does not change the passed array. @param affine The array to fill with affine values. Ignored if NULL. */ - bool asAffine(SkScalar affine[6]) const; + bool SK_WARN_UNUSED_RESULT asAffine(SkScalar affine[6]) const; + + /** Set the matrix to the specified affine values. + * Note: these are passed in column major order. + */ + void setAffine(const SkScalar affine[6]); /** Apply this matrix to the array of points specified by src, and write the transformed points into the array of points specified by dst. @@ -380,7 +429,12 @@ class SK_API SkMatrix { @param count The number of points in src to read, and then transform into dst. */ - void mapPoints(SkPoint dst[], const SkPoint src[], int count) const; + void mapPoints(SkPoint dst[], const SkPoint src[], int count) const { + SkASSERT((dst && src && count > 0) || 0 == count); + // no partial overlap + SkASSERT(src == dst || &dst[count] <= &src[0] || &src[count] <= &dst[0]); + this->getMapPtsProc()(*this, dst, src, count); + } /** Apply this matrix to the array of points, overwriting it with the transformed values. @@ -436,6 +490,12 @@ class SK_API SkMatrix { this->getMapXYProc()(*this, x, y, result); } + SkPoint mapXY(SkScalar x, SkScalar y) const { + SkPoint result; + this->getMapXYProc()(*this, x, y, &result); + return result; + } + /** Apply this matrix to the array of vectors specified by src, and write the transformed vectors into the array of vectors specified by dst. This is similar to mapPoints, but ignores any translation in the matrix. @@ -459,6 +519,17 @@ class SK_API SkMatrix { this->mapVectors(vecs, vecs, count); } + void mapVector(SkScalar dx, SkScalar dy, SkVector* result) const { + SkVector vec = { dx, dy }; + this->mapVectors(result, &vec, 1); + } + + SkVector mapVector(SkScalar dx, SkScalar dy) const { + SkVector vec = { dx, dy }; + this->mapVectors(&vec, &vec, 1); + return vec; + } + /** Apply this matrix to the src rectangle, and write the transformed rectangle into dst. This is accomplished by transforming the 4 corners of src, and then setting dst to the bounds of those points. @@ -490,6 +561,12 @@ class SK_API SkMatrix { this->mapPoints(dst, 4); } + /** + * Maps a rect to another rect, asserting (in debug mode) that the matrix only contains + * scale and translate elements. If it contains other elements, the results are undefined. + */ + void mapRectScaleTranslate(SkRect* dst, const SkRect& src) const; + /** Return the mean radius of a circle after it has been mapped by this matrix. NOTE: in perspective this value assumes the circle has its center at the origin. @@ -520,11 +597,16 @@ class SK_API SkMatrix { return GetMapPtsProc(this->getType()); } + /** Returns true if the matrix can be stepped in X (not complex + perspective). + */ + bool isFixedStepInX() const; + /** If the matrix can be stepped in X (not complex perspective) - then return true and if step[XY] is not null, return the step[XY] value. - If it cannot, return false and ignore step. + then return the step value. + If it cannot, behavior is undefined. */ - bool fixedStepInX(SkScalar y, SkFixed* stepX, SkFixed* stepY) const; + SkVector fixedStepInX(SkScalar y) const; /** Efficient comparison of two matrices. It distinguishes between zero and * negative zero. It will return false when the sign of zero values is the @@ -538,8 +620,8 @@ class SK_API SkMatrix { return 0 == memcmp(fMat, m.fMat, sizeof(fMat)); } - friend bool operator==(const SkMatrix& a, const SkMatrix& b); - friend bool operator!=(const SkMatrix& a, const SkMatrix& b) { + friend SK_API bool operator==(const SkMatrix& a, const SkMatrix& b); + friend SK_API bool operator!=(const SkMatrix& a, const SkMatrix& b) { return !(a == b); } @@ -559,24 +641,46 @@ class SK_API SkMatrix { */ size_t readFromMemory(const void* buffer, size_t length); - SkDEVCODE(void dump() const;) - SkDEVCODE(void toString(SkString*) const;) + void dump() const; + void toString(SkString*) const; + + /** + * Calculates the minimum scaling factor of the matrix as computed from the SVD of the upper + * left 2x2. If the max scale factor cannot be computed (for example overflow or perspective) + * -1 is returned. + * + * @return minimum scale factor + */ + SkScalar getMinScale() const; /** - * Calculates the minimum stretching factor of the matrix. If the matrix has - * perspective -1 is returned. + * Calculates the maximum scaling factor of the matrix as computed from the SVD of the upper + * left 2x2. If the max scale factor cannot be computed (for example overflow or perspective) + * -1 is returned. * - * @return minumum strecthing factor + * @return maximum scale factor */ - SkScalar getMinStretch() const; + SkScalar getMaxScale() const; /** - * Calculates the maximum stretching factor of the matrix. If the matrix has - * perspective -1 is returned. + * Gets both the min and max scale factors. The min scale factor is scaleFactors[0] and the max + * is scaleFactors[1]. If the min/max scale factors cannot be computed false is returned and the + * values of scaleFactors[] are undefined. + */ + bool SK_WARN_UNUSED_RESULT getMinMaxScales(SkScalar scaleFactors[2]) const; + + /** + * Attempt to decompose this matrix into a scale-only component and whatever remains, where + * the scale component is to be applied first. + * + * M -> Remaining * Scale + * + * On success, return true and assign the scale and remaining components (assuming their + * respective parameters are not null). On failure return false and ignore the parameters. * - * @return maximum strecthing factor + * Possible reasons to fail: perspective, one or more scale factors are zero. */ - SkScalar getMaxStretch() const; + bool decomposeScale(SkSize* scale, SkMatrix* remaining = NULL) const; /** * Return a reference to a const identity matrix @@ -589,6 +693,15 @@ class SK_API SkMatrix { */ static const SkMatrix& InvalidMatrix(); + /** + * Return the concatenation of two matrices, a * b. + */ + static SkMatrix Concat(const SkMatrix& a, const SkMatrix& b) { + SkMatrix result; + result.setConcat(a, b); + return result; + } + /** * Testing routine; the matrix's type cache should never need to be * manually invalidated during normal use. @@ -597,6 +710,37 @@ class SK_API SkMatrix { this->setTypeMask(kUnknown_Mask); } + /** + * Initialize the matrix to be scale + post-translate. + */ + void setScaleTranslate(SkScalar sx, SkScalar sy, SkScalar tx, SkScalar ty) { + fMat[kMScaleX] = sx; + fMat[kMSkewX] = 0; + fMat[kMTransX] = tx; + + fMat[kMSkewY] = 0; + fMat[kMScaleY] = sy; + fMat[kMTransY] = ty; + + fMat[kMPersp0] = 0; + fMat[kMPersp1] = 0; + fMat[kMPersp2] = 1; + + unsigned mask = 0; + if (sx != 1 || sy != 1) { + mask |= kScale_Mask; + } + if (tx || ty) { + mask |= kTranslate_Mask; + } + this->setTypeMask(mask | kRectStaysRect_Mask); + } + + /** + * Are all elements of the matrix finite? + */ + bool isFinite() const { return SkScalarsAreFinite(fMat, 9); } + private: enum { /** Set if the matrix will map a rectangle to another rectangle. This @@ -629,6 +773,8 @@ class SK_API SkMatrix { SkScalar fMat[9]; mutable uint32_t fTypeMask; + static void ComputeInv(SkScalar dst[9], const SkScalar src[9], double invDet, bool isPersp); + uint8_t computeTypeMask() const; uint8_t computePerspectiveTypeMask() const; @@ -648,7 +794,7 @@ class SK_API SkMatrix { void clearTypeMask(int mask) { // only allow a valid mask SkASSERT((mask & kAllMasks) == mask); - fTypeMask &= ~mask; + fTypeMask = fTypeMask & ~mask; } TypeMask getPerspectiveTypeMaskOnly() const { @@ -690,14 +836,15 @@ class SK_API SkMatrix { static void Scale_pts(const SkMatrix&, SkPoint dst[], const SkPoint[], int); static void ScaleTrans_pts(const SkMatrix&, SkPoint dst[], const SkPoint[], int count); - static void Rot_pts(const SkMatrix&, SkPoint dst[], const SkPoint[], int); - static void RotTrans_pts(const SkMatrix&, SkPoint dst[], const SkPoint[], - int count); static void Persp_pts(const SkMatrix&, SkPoint dst[], const SkPoint[], int); + static void Affine_vpts(const SkMatrix&, SkPoint dst[], const SkPoint[], int); + static const MapPtsProc gMapPtsProcs[]; friend class SkPerspIter; + friend class SkMatrixPriv; }; +SK_END_REQUIRE_DENSE #endif diff --git a/libskia/include/utils/SkMatrix44.h b/libskia/include/core/SkMatrix44.h similarity index 80% rename from libskia/include/utils/SkMatrix44.h rename to libskia/include/core/SkMatrix44.h index 26247a01..9820ee58 100644 --- a/libskia/include/utils/SkMatrix44.h +++ b/libskia/include/core/SkMatrix44.h @@ -29,7 +29,20 @@ static inline double SkMScalarToDouble(double x) { return x; } + static inline double SkMScalarAbs(double x) { + return fabs(x); + } static const SkMScalar SK_MScalarPI = 3.141592653589793; + + #define SkMScalarFloor(x) sk_double_floor(x) + #define SkMScalarCeil(x) sk_double_ceil(x) + #define SkMScalarRound(x) sk_double_round(x) + + #define SkMScalarFloorToInt(x) sk_double_floor2int(x) + #define SkMScalarCeilToInt(x) sk_double_ceil2int(x) + #define SkMScalarRoundToInt(x) sk_double_round2int(x) + + #elif defined SK_MSCALAR_IS_FLOAT #ifdef SK_MSCALAR_IS_DOUBLE #error "can't define MSCALAR both as DOUBLE and FLOAT" @@ -48,11 +61,25 @@ static inline double SkMScalarToDouble(float x) { return static_cast(x); } + static inline float SkMScalarAbs(float x) { + return sk_float_abs(x); + } static const SkMScalar SK_MScalarPI = 3.14159265f; + + #define SkMScalarFloor(x) sk_float_floor(x) + #define SkMScalarCeil(x) sk_float_ceil(x) + #define SkMScalarRound(x) sk_float_round(x) + + #define SkMScalarFloorToInt(x) sk_float_floor2int(x) + #define SkMScalarCeilToInt(x) sk_float_ceil2int(x) + #define SkMScalarRoundToInt(x) sk_float_round2int(x) + #endif -#define SkMScalarToScalar SkMScalarToFloat -#define SkScalarToMScalar SkFloatToMScalar +#define SkIntToMScalar(n) static_cast(n) + +#define SkMScalarToScalar(x) SkMScalarToFloat(x) +#define SkScalarToMScalar(x) SkFloatToMScalar(x) static const SkMScalar SK_MScalar1 = 1; @@ -109,8 +136,15 @@ class SK_API SkMatrix44 { kIdentity_Constructor }; - SkMatrix44(Uninitialized_Constructor) { } - SkMatrix44(Identity_Constructor) { this->setIdentity(); } + SkMatrix44(Uninitialized_Constructor) {} + + constexpr SkMatrix44(Identity_Constructor) + : fMat{{ 1, 0, 0, 0, }, + { 0, 1, 0, 0, }, + { 0, 0, 1, 0, }, + { 0, 0, 0, 1, }} + , fTypeMask(kIdentity_Mask) + {} SK_ATTR_DEPRECATED("use the constructors that take an enum") SkMatrix44() { this->setIdentity(); } @@ -198,6 +232,17 @@ class SK_API SkMatrix44 { return !(this->getType() & ~(kScale_Mask | kTranslate_Mask)); } + /** + * Returns true if the matrix only contains scale or is identity. + */ + inline bool isScale() const { + return !(this->getType() & ~kScale_Mask); + } + + inline bool hasPerspective() const { + return SkToBool(this->getType() & kPerspective_Mask); + } + void setIdentity(); inline void reset() { this->setIdentity();} @@ -243,6 +288,10 @@ class SK_API SkMatrix44 { * array. The given array must have room for exactly 16 entries. Whenever * possible, they will try to use memcpy rather than an entry-by-entry * copy. + * + * Col major indicates that consecutive elements of columns will be stored + * contiguously in memory. Row major indicates that consecutive elements + * of rows will be stored contiguously in memory. */ void asColMajorf(float[]) const; void asColMajord(double[]) const; @@ -253,6 +302,11 @@ class SK_API SkMatrix44 { * array. The given array must have room for exactly 16 entries. Whenever * possible, they will try to use memcpy rather than an entry-by-entry * copy. + * + * Col major indicates that input memory will be treated as if consecutive + * elements of columns are stored contiguously in memory. Row major + * indicates that input memory will be treated as if consecutive elements + * of rows are stored contiguously in memory. */ void setColMajorf(const float[]); void setColMajord(const double[]); @@ -268,10 +322,12 @@ class SK_API SkMatrix44 { #endif /* This sets the top-left of the matrix and clears the translation and - * perspective components (with [3][3] set to 1). */ + * perspective components (with [3][3] set to 1). mXY is interpreted + * as the matrix entry at col = X, row = Y. */ void set3x3(SkMScalar m00, SkMScalar m01, SkMScalar m02, SkMScalar m10, SkMScalar m11, SkMScalar m12, SkMScalar m20, SkMScalar m21, SkMScalar m22); + void set3x3RowMajorf(const float[]); void setTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz); void preTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz); @@ -320,7 +376,8 @@ class SK_API SkMatrix44 { } /** If this is invertible, return that in inverse and return true. If it is - not invertible, return false and ignore the inverse parameter. + not invertible, return false and leave the inverse parameter in an + unspecified state. */ bool invert(SkMatrix44* inverse) const; @@ -373,11 +430,24 @@ class SK_API SkMatrix44 { void map2(const float src2[], int count, float dst4[]) const; void map2(const double src2[], int count, double dst4[]) const; + /** Returns true if transformating an axis-aligned square in 2d by this matrix + will produce another 2d axis-aligned square; typically means the matrix + is a scale with perhaps a 90-degree rotation. A 3d rotation through 90 + degrees into a perpendicular plane collapses a square to a line, but + is still considered to be axis-aligned. + + By default, tolerates very slight error due to float imprecisions; + a 90-degree rotation can still end up with 10^-17 of + "non-axis-aligned" result. + */ + bool preserves2dAxisAlignment(SkMScalar epsilon = SK_ScalarNearlyZero) const; + void dump() const; double determinant() const; private: + /* This is indexed by [col][row]. */ SkMScalar fMat[4][4]; mutable unsigned fTypeMask; @@ -387,6 +457,9 @@ class SK_API SkMatrix44 { kAllPublic_Masks = 0xF }; + void as3x4RowMajorf(float[]) const; + void set3x4RowMajorf(const float[]); + SkMScalar transX() const { return fMat[3][0]; } SkMScalar transY() const { return fMat[3][1]; } SkMScalar transZ() const { return fMat[3][2]; } @@ -417,6 +490,8 @@ class SK_API SkMatrix44 { inline bool isTriviallyIdentity() const { return 0 == fTypeMask; } + + friend class SkColorSpace; }; #endif diff --git a/libskia/include/core/SkMetaData.h b/libskia/include/core/SkMetaData.h index 5db437c9..c8ca7f14 100644 --- a/libskia/include/core/SkMetaData.h +++ b/libskia/include/core/SkMetaData.h @@ -81,7 +81,7 @@ class SK_API SkMetaData { bool hasData(const char name[], const void* data, size_t byteCount) const { size_t len; const void* ptr = this->findData(name, &len); - return NULL != ptr && len == byteCount && !memcmp(ptr, data, len); + return ptr && len == byteCount && !memcmp(ptr, data, len); } void setS32(const char name[], int32_t value); diff --git a/libskia/src/gpu/SkGrTexturePixelRef.cpp b/libskia/include/core/SkMilestone.h similarity index 58% rename from libskia/src/gpu/SkGrTexturePixelRef.cpp rename to libskia/include/core/SkMilestone.h index ae2bbddc..221f0716 100644 --- a/libskia/src/gpu/SkGrTexturePixelRef.cpp +++ b/libskia/include/core/SkMilestone.h @@ -1,11 +1,9 @@ - /* - * Copyright 2010 Google Inc. + * Copyright 2016 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ - - - -#include "SkGrTexturePixelRef.h" +#ifndef SK_MILESTONE +#define SK_MILESTONE 57 +#endif diff --git a/libskia/include/core/SkMultiPictureDraw.h b/libskia/include/core/SkMultiPictureDraw.h new file mode 100644 index 00000000..9995721a --- /dev/null +++ b/libskia/include/core/SkMultiPictureDraw.h @@ -0,0 +1,75 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkMultiPictureDraw_DEFINED +#define SkMultiPictureDraw_DEFINED + +#include "../private/SkTDArray.h" +#include "SkMatrix.h" + +class SkCanvas; +class SkPaint; +class SkPicture; + +/** \class SkMultiPictureDraw + + The MultiPictureDraw object accepts several picture/canvas pairs and + then attempts to optimally draw the pictures into the canvases, sharing + as many resources as possible. +*/ +class SK_API SkMultiPictureDraw { +public: + /** + * Create an object to optimize the drawing of multiple pictures. + * @param reserve Hint for the number of add calls expected to be issued + */ + SkMultiPictureDraw(int reserve = 0); + ~SkMultiPictureDraw() { this->reset(); } + + /** + * Add a canvas/picture pair for later rendering. + * @param canvas the canvas in which to draw picture + * @param picture the picture to draw into canvas + * @param matrix if non-NULL, applied to the CTM when drawing + * @param paint if non-NULL, draw picture to a temporary buffer + * and then apply the paint when the result is drawn + */ + void add(SkCanvas* canvas, + const SkPicture* picture, + const SkMatrix* matrix = NULL, + const SkPaint* paint = NULL); + + /** + * Perform all the previously added draws. This will reset the state + * of this object. If flush is true, all canvases are flushed after + * draw. + */ + void draw(bool flush = false); + + /** + * Abandon all buffered draws and reset to the initial state. + */ + void reset(); + +private: + struct DrawData { + SkCanvas* fCanvas; + const SkPicture* fPicture; // reffed + SkMatrix fMatrix; + SkPaint* fPaint; // owned + + void init(SkCanvas*, const SkPicture*, const SkMatrix*, const SkPaint*); + void draw(); + + static void Reset(SkTDArray&); + }; + + SkTDArray fThreadSafeDrawData; + SkTDArray fGPUDrawData; +}; + +#endif diff --git a/libskia/include/core/SkOSFile.h b/libskia/include/core/SkOSFile.h index b75fe6cf..87613559 100644 --- a/libskia/include/core/SkOSFile.h +++ b/libskia/include/core/SkOSFile.h @@ -1,4 +1,3 @@ - /* * Copyright 2006 The Android Open Source Project * @@ -12,51 +11,40 @@ #ifndef SkOSFile_DEFINED #define SkOSFile_DEFINED -#include "SkString.h" - -#if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_ANDROID) || defined(SK_BUILD_FOR_IOS) - #include -#endif - -#include // ptrdiff_t +#include -struct SkFILE; +#include "SkString.h" enum SkFILE_Flags { kRead_SkFILE_Flag = 0x01, kWrite_SkFILE_Flag = 0x02 }; -#ifdef _WIN32 -const static char SkPATH_SEPARATOR = '\\'; -#else -const static char SkPATH_SEPARATOR = '/'; -#endif - -SkFILE* sk_fopen(const char path[], SkFILE_Flags); -void sk_fclose(SkFILE*); +FILE* sk_fopen(const char path[], SkFILE_Flags); +void sk_fclose(FILE*); -size_t sk_fgetsize(SkFILE*); +size_t sk_fgetsize(FILE*); /** Return true if the file could seek back to the beginning */ -bool sk_frewind(SkFILE*); +bool sk_frewind(FILE*); -size_t sk_fread(void* buffer, size_t byteCount, SkFILE*); -size_t sk_fwrite(const void* buffer, size_t byteCount, SkFILE*); +size_t sk_fread(void* buffer, size_t byteCount, FILE*); +size_t sk_fwrite(const void* buffer, size_t byteCount, FILE*); -char* sk_fgets(char* str, int size, SkFILE* f); +char* sk_fgets(char* str, int size, FILE* f); -void sk_fflush(SkFILE*); +void sk_fflush(FILE*); +void sk_fsync(FILE*); -bool sk_fseek(SkFILE*, size_t); -bool sk_fmove(SkFILE*, long); -size_t sk_ftell(SkFILE*); +bool sk_fseek(FILE*, size_t); +bool sk_fmove(FILE*, long); +size_t sk_ftell(FILE*); /** Maps a file into memory. Returns the address and length on success, NULL otherwise. * The mapping is read only. * When finished with the mapping, free the returned pointer with sk_fmunmap. */ -void* sk_fmmap(SkFILE* f, size_t* length); +void* sk_fmmap(FILE* f, size_t* length); /** Maps a file descriptor into memory. Returns the address and length on success, NULL otherwise. * The mapping is read only. @@ -70,21 +58,23 @@ void* sk_fdmmap(int fd, size_t* length); void sk_fmunmap(const void* addr, size_t length); /** Returns true if the two point at the exact same filesystem object. */ -bool sk_fidentical(SkFILE* a, SkFILE* b); +bool sk_fidentical(FILE* a, FILE* b); /** Returns the underlying file descriptor for the given file. * The return value will be < 0 on failure. */ -int sk_fileno(SkFILE* f); +int sk_fileno(FILE* f); -// Returns true if something (file, directory, ???) exists at this path. -bool sk_exists(const char *path); +/** Returns true if something (file, directory, ???) exists at this path, + * and has the specified access flags. + */ +bool sk_exists(const char *path, SkFILE_Flags = (SkFILE_Flags)0); // Returns true if a directory exists at this path. bool sk_isdir(const char *path); // Have we reached the end of the file? -int sk_feof(SkFILE *); +int sk_feof(FILE *); // Create a new directory at this path; returns true if successful. @@ -107,53 +97,10 @@ class SkOSFile { */ bool next(SkString* name, bool getDir = false); + static const size_t kStorageSize = 40; private: -#ifdef SK_BUILD_FOR_WIN - HANDLE fHandle; - uint16_t* fPath16; -#elif defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_ANDROID) || defined(SK_BUILD_FOR_IOS) - DIR* fDIR; - SkString fPath, fSuffix; -#endif + SkAlignedSStorage fSelf; }; }; -class SkUTF16_Str { -public: - SkUTF16_Str(const char src[]); - ~SkUTF16_Str() - { - sk_free(fStr); - } - const uint16_t* get() const { return fStr; } - -private: - uint16_t* fStr; -}; - -/** - * Functions for modifying SkStrings which represent paths on the filesystem. - */ -class SkOSPath { -public: - /** - * Assembles rootPath and relativePath into a single path, like this: - * rootPath/relativePath. - * It is okay to call with a NULL rootPath and/or relativePath. A path - * separator will still be inserted. - * - * Uses SkPATH_SEPARATOR, to work on all platforms. - */ - static SkString SkPathJoin(const char *rootPath, const char *relativePath); - - /** - * Return the name of the file, ignoring the directory structure. - * Behaves like python's os.path.basename. If the fullPath is - * /dir/subdir/, an empty string is returned. - * @param fullPath Full path to the file. - * @return SkString The basename of the file - anything beyond the - * final slash, or the full name if there is no slash. - */ - static SkString SkBasename(const char* fullPath); -}; #endif diff --git a/libskia/include/core/SkPackBits.h b/libskia/include/core/SkPackBits.h deleted file mode 100644 index f0614a08..00000000 --- a/libskia/include/core/SkPackBits.h +++ /dev/null @@ -1,79 +0,0 @@ - -/* - * Copyright 2008 The Android Open Source Project - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - - -#ifndef SkPackBits_DEFINED -#define SkPackBits_DEFINED - -#include "SkTypes.h" - -class SkPackBits { -public: - /** Given the number of 16bit values that will be passed to Pack16, - returns the worst-case size needed for the dst[] buffer. - */ - static size_t ComputeMaxSize16(int count); - - /** Given the number of 8bit values that will be passed to Pack8, - returns the worst-case size needed for the dst[] buffer. - */ - static size_t ComputeMaxSize8(int count); - - /** Write the src array into a packed format. The packing process may end - up writing more bytes than it read, so dst[] must be large enough. - @param src Input array of 16bit values - @param count Number of entries in src[] - @param dst Buffer (allocated by caller) to write the packed data - into - @return the number of bytes written to dst[] - */ - static size_t Pack16(const uint16_t src[], int count, uint8_t dst[]); - - /** Write the src array into a packed format. The packing process may end - up writing more bytes than it read, so dst[] must be large enough. - @param src Input array of 8bit values - @param count Number of entries in src[] - @param dst Buffer (allocated by caller) to write the packed data - into - @return the number of bytes written to dst[] - */ - static size_t Pack8(const uint8_t src[], int count, uint8_t dst[]); - - /** Unpack the data in src[], and expand it into dst[]. The src[] data was - written by a previous call to Pack16. - @param src Input data to unpack, previously created by Pack16. - @param srcSize Number of bytes of src to unpack - @param dst Buffer (allocated by caller) to expand the src[] into. - @return the number of dst elements (not bytes) written into dst. - */ - static int Unpack16(const uint8_t src[], size_t srcSize, uint16_t dst[]); - - /** Unpack the data in src[], and expand it into dst[]. The src[] data was - written by a previous call to Pack8. - @param src Input data to unpack, previously created by Pack8. - @param srcSize Number of bytes of src to unpack - @param dst Buffer (allocated by caller) to expand the src[] into. - @return the number of bytes written into dst. - */ - static int Unpack8(const uint8_t src[], size_t srcSize, uint8_t dst[]); - - /** Unpack the data from src[], skip the first dstSkip bytes, then write - dstWrite bytes into dst[]. The src[] data was written by a previous - call to Pack8. Return the number of bytes actually writtten into dst[] - @param src Input data to unpack, previously created by Pack8. - @param dst Buffer (allocated by caller) to expand the src[] into. - @param dstSkip Number of bytes of unpacked src to skip before writing - into dst - @param dstWrite Number of bytes of unpacked src to write into dst (after - skipping dstSkip bytes) - */ - static void Unpack8(uint8_t dst[], size_t dstSkip, size_t dstWrite, - const uint8_t src[]); -}; - -#endif diff --git a/libskia/include/core/SkPaint.h b/libskia/include/core/SkPaint.h index 7dc3a4e0..de3b4792 100644 --- a/libskia/include/core/SkPaint.h +++ b/libskia/include/core/SkPaint.h @@ -1,5 +1,3 @@ - - /* * Copyright 2006 The Android Open Source Project * @@ -7,26 +5,24 @@ * found in the LICENSE file. */ - #ifndef SkPaint_DEFINED #define SkPaint_DEFINED +#include "SkBlendMode.h" #include "SkColor.h" -#include "SkDrawLooper.h" +#include "SkFilterQuality.h" #include "SkMatrix.h" -#include "SkXfermode.h" -#ifdef SK_BUILD_FOR_ANDROID -#include "SkPaintOptionsAndroid.h" -#endif +#include "SkRefCnt.h" -class SkAnnotation; +class SkAutoDescriptor; class SkAutoGlyphCache; class SkColorFilter; +class SkData; class SkDescriptor; -struct SkDeviceProperties; -class SkFlattenableReadBuffer; -class SkFlattenableWriteBuffer; -struct SkGlyph; +class SkDrawLooper; +class SkReadBuffer; +class SkWriteBuffer; +class SkGlyph; struct SkRect; class SkGlyphCache; class SkImageFilter; @@ -35,14 +31,12 @@ class SkPath; class SkPathEffect; struct SkPoint; class SkRasterizer; +struct SkScalerContextEffects; class SkShader; +class SkSurfaceProps; +class SkTextBlob; class SkTypeface; -typedef const SkGlyph& (*SkDrawCacheProc)(SkGlyphCache*, const char**, - SkFixed x, SkFixed y); - -typedef const SkGlyph& (*SkMeasureCacheProc)(SkGlyphCache*, const char**); - #define kBicubicFilterBitmap_Flag kHighQualityFilterBitmap_Flag /** \class SkPaint @@ -50,30 +44,32 @@ typedef const SkGlyph& (*SkMeasureCacheProc)(SkGlyphCache*, const char**); The SkPaint class holds the style and color information about how to draw geometries, text and bitmaps. */ - class SK_API SkPaint { - enum { - // DEPRECATED -- use setFilterLevel instead - kFilterBitmap_Flag = 0x02, // temporary flag - // DEPRECATED -- use setFilterLevel instead - kHighQualityFilterBitmap_Flag = 0x4000, // temporary flag - // DEPRECATED -- use setFilterLevel instead - kHighQualityDownsampleBitmap_Flag = 0x8000, // temporary flag - }; public: SkPaint(); SkPaint(const SkPaint& paint); + SkPaint(SkPaint&& paint); ~SkPaint(); SkPaint& operator=(const SkPaint&); + SkPaint& operator=(SkPaint&&); + /** operator== may give false negatives: two paints that draw equivalently + may return false. It will never give false positives: two paints that + are not equivalent always return false. + */ SK_API friend bool operator==(const SkPaint& a, const SkPaint& b); friend bool operator!=(const SkPaint& a, const SkPaint& b) { return !(a == b); } - void flatten(SkFlattenableWriteBuffer&) const; - void unflatten(SkFlattenableReadBuffer&); + /** getHash() is a shallow hash, with the same limitations as operator==. + * If operator== returns true for two paints, getHash() returns the same value for each. + */ + uint32_t getHash() const; + + void flatten(SkWriteBuffer&) const; + void unflatten(SkReadBuffer&); /** Restores the paint to its initial settings. */ @@ -97,7 +93,7 @@ class SK_API SkPaint { }; Hinting getHinting() const { - return static_cast(fHinting); + return static_cast(fBitfields.fHinting); } void setHinting(Hinting hintingLevel); @@ -127,7 +123,7 @@ class SK_API SkPaint { /** Return the paint's flags. Use the Flag enum to test flag values. @return the paint's flags (see enums ending in _Flag for bit masks) */ - uint32_t getFlags() const { return fFlags; } + uint32_t getFlags() const { return fBitfields.fFlags; } /** Set the paint's flags. Use the Flag enum to specific flag values. @param flags The new flag bits for the paint (see Flags enum) @@ -284,41 +280,19 @@ class SK_API SkPaint { */ void setDevKernText(bool devKernText); - enum FilterLevel { - kNone_FilterLevel, - kLow_FilterLevel, - kMedium_FilterLevel, - kHigh_FilterLevel - }; - /** * Return the filter level. This affects the quality (and performance) of * drawing scaled images. */ - FilterLevel getFilterLevel() const; - - /** - * Set the filter level. This affects the quality (and performance) of - * drawing scaled images. - */ - void setFilterLevel(FilterLevel); - - /** - * If the predicate is true, set the filterLevel to Low, else set it to - * None. - */ - SK_ATTR_DEPRECATED("use setFilterLevel") - void setFilterBitmap(bool doFilter) { - this->setFilterLevel(doFilter ? kLow_FilterLevel : kNone_FilterLevel); + SkFilterQuality getFilterQuality() const { + return (SkFilterQuality)fBitfields.fFilterQuality; } /** - * Returns true if getFilterLevel() returns anything other than None. + * Set the filter quality. This affects the quality (and performance) of + * drawing scaled images. */ - SK_ATTR_DEPRECATED("use getFilterLevel") - bool isFilterBitmap() const { - return kNone_FilterLevel != this->getFilterLevel(); - } + void setFilterQuality(SkFilterQuality quality); /** Styles apply to rect, oval, path, and text. Bitmaps are always drawn in "fill", and lines are always drawn in @@ -343,7 +317,7 @@ class SK_API SkPaint { kFill_Style). @return the paint's Style */ - Style getStyle() const { return (Style)fStyle; } + Style getStyle() const { return (Style)fBitfields.fStyle; } /** Set the paint's style, used for controlling how primitives' geometries are interpreted (except for drawBitmap, which always assumes @@ -422,15 +396,25 @@ class SK_API SkPaint { /** Cap enum specifies the settings for the paint's strokecap. This is the treatment that is applied to the beginning and end of each non-closed contour (e.g. lines). + + If the cap is round or square, the caps are drawn when the contour has + a zero length. Zero length contours can be created by following moveTo + with a lineTo at the same point, or a moveTo followed by a close. + + A dash with an on interval of zero also creates a zero length contour. + + The zero length contour draws the square cap without rotation, since + the no direction can be inferred. */ enum Cap { kButt_Cap, //!< begin/end contours with no extension kRound_Cap, //!< begin/end contours with a semi-circle extension kSquare_Cap, //!< begin/end contours with a half square extension - kCapCount, + kLast_Cap = kSquare_Cap, kDefault_Cap = kButt_Cap }; + static constexpr int kCapCount = kLast_Cap + 1; /** Join enum specifies the settings for the paint's strokejoin. This is the treatment that is applied to corners in paths and rectangles. @@ -440,16 +424,17 @@ class SK_API SkPaint { kRound_Join, //!< connect path segments with a round join kBevel_Join, //!< connect path segments with a flat bevel join - kJoinCount, + kLast_Join = kBevel_Join, kDefault_Join = kMiter_Join }; + static constexpr int kJoinCount = kLast_Join + 1; /** Return the paint's stroke cap type, controlling how the start and end of stroked lines and paths are treated. @return the line cap style for the paint, used whenever the paint's style is Stroke or StrokeAndFill. */ - Cap getStrokeCap() const { return (Cap)fCapType; } + Cap getStrokeCap() const { return (Cap)fBitfields.fCapType; } /** Set the paint's stroke cap type. @param cap set the paint's line cap style, used whenever the paint's @@ -461,7 +446,7 @@ class SK_API SkPaint { @return the paint's line join style, used whenever the paint's style is Stroke or StrokeAndFill. */ - Join getStrokeJoin() const { return (Join)fJoinType; } + Join getStrokeJoin() const { return (Join)fBitfields.fJoinType; } /** Set the paint's stroke join type. @param join set the paint's line join style, used whenever the paint's @@ -478,18 +463,24 @@ class SK_API SkPaint { * @param src input path * @param dst output path (may be the same as src) * @param cullRect If not null, the dst path may be culled to this rect. + * @param resScale If > 1, increase precision, else if (0 < res < 1) reduce precision + * in favor of speed/size. * @return true if the path should be filled, or false if it should be * drawn with a hairline (width == 0) */ - bool getFillPath(const SkPath& src, SkPath* dst, - const SkRect* cullRect = NULL) const; + bool getFillPath(const SkPath& src, SkPath* dst, const SkRect* cullRect, + SkScalar resScale = 1) const; + + bool getFillPath(const SkPath& src, SkPath* dst) const { + return this->getFillPath(src, dst, NULL, 1); + } /** Get the paint's shader object.

The shader's reference count is not affected. @return the paint's shader (or NULL) */ - SkShader* getShader() const { return fShader; } + SkShader* getShader() const { return fShader.get(); } /** Set or clear the shader object. * Shaders specify the source color(s) for what is being drawn. If a paint @@ -499,62 +490,44 @@ class SK_API SkPaint { * once (e.g. bitmap tiling or gradient) and then change its transparency * w/o having to modify the original shader... only the paint's alpha needs * to be modified. - *

+ * + * There is an exception to this only-respect-paint's-alpha rule: If the shader only generates + * alpha (e.g. SkShader::CreateBitmapShader(bitmap, ...) where bitmap's colortype is kAlpha_8) + * then the shader will use the paint's entire color to "colorize" its output (modulating the + * bitmap's alpha with the paint's color+alpha). + * * Pass NULL to clear any previous shader. * As a convenience, the parameter passed is also returned. * If a previous shader exists, its reference count is decremented. * If shader is not NULL, its reference count is incremented. * @param shader May be NULL. The shader to be installed in the paint - * @return shader */ - SkShader* setShader(SkShader* shader); + void setShader(sk_sp); /** Get the paint's colorfilter. If there is a colorfilter, its reference count is not changed. @return the paint's colorfilter (or NULL) */ - SkColorFilter* getColorFilter() const { return fColorFilter; } + SkColorFilter* getColorFilter() const { return fColorFilter.get(); } - /** Set or clear the paint's colorfilter, returning the parameter. + /** Set or clear the paint's colorfilter.

If the paint already has a filter, its reference count is decremented. If filter is not NULL, its reference count is incremented. @param filter May be NULL. The filter to be installed in the paint - @return filter - */ - SkColorFilter* setColorFilter(SkColorFilter* filter); - - /** Get the paint's xfermode object. -

- The xfermode's reference count is not affected. - @return the paint's xfermode (or NULL) - */ - SkXfermode* getXfermode() const { return fXfermode; } - - /** Set or clear the xfermode object. -

- Pass NULL to clear any previous xfermode. - As a convenience, the parameter passed is also returned. - If a previous xfermode exists, its reference count is decremented. - If xfermode is not NULL, its reference count is incremented. - @param xfermode May be NULL. The new xfermode to be installed in the - paint - @return xfermode */ - SkXfermode* setXfermode(SkXfermode* xfermode); + void setColorFilter(sk_sp); - /** Create an xfermode based on the specified Mode, and assign it into the - paint, returning the mode that was set. If the Mode is SrcOver, then - the paint's xfermode is set to null. - */ - SkXfermode* setXfermodeMode(SkXfermode::Mode); + SkBlendMode getBlendMode() const { return (SkBlendMode)fBlendMode; } + bool isSrcOver() const { return (SkBlendMode)fBlendMode == SkBlendMode::kSrcOver; } + void setBlendMode(SkBlendMode mode) { fBlendMode = (unsigned)mode; } /** Get the paint's patheffect object.

The patheffect reference count is not affected. @return the paint's patheffect (or NULL) */ - SkPathEffect* getPathEffect() const { return fPathEffect; } + SkPathEffect* getPathEffect() const { return fPathEffect.get(); } /** Set or clear the patheffect object.

@@ -566,14 +539,14 @@ class SK_API SkPaint { paint @return effect */ - SkPathEffect* setPathEffect(SkPathEffect* effect); + void setPathEffect(sk_sp); /** Get the paint's maskfilter object.

The maskfilter reference count is not affected. @return the paint's maskfilter (or NULL) */ - SkMaskFilter* getMaskFilter() const { return fMaskFilter; } + SkMaskFilter* getMaskFilter() const { return fMaskFilter.get(); } /** Set or clear the maskfilter object.

@@ -585,7 +558,7 @@ class SK_API SkPaint { the paint @return maskfilter */ - SkMaskFilter* setMaskFilter(SkMaskFilter* maskfilter); + void setMaskFilter(sk_sp); // These attributes are for text/fonts @@ -595,7 +568,7 @@ class SK_API SkPaint { measuring text. The typeface reference count is not affected. @return the paint's typeface (or NULL) */ - SkTypeface* getTypeface() const { return fTypeface; } + SkTypeface* getTypeface() const { return fTypeface.get(); } /** Set or clear the typeface object.

@@ -607,14 +580,14 @@ class SK_API SkPaint { paint @return typeface */ - SkTypeface* setTypeface(SkTypeface* typeface); + void setTypeface(sk_sp); /** Get the paint's rasterizer (or NULL).

The raster controls how paths/text are turned into alpha masks. @return the paint's rasterizer (or NULL) */ - SkRasterizer* getRasterizer() const { return fRasterizer; } + SkRasterizer* getRasterizer() const { return fRasterizer.get(); } /** Set or clear the rasterizer object.

@@ -627,39 +600,29 @@ class SK_API SkPaint { the paint. @return rasterizer */ - SkRasterizer* setRasterizer(SkRasterizer* rasterizer); - - SkImageFilter* getImageFilter() const { return fImageFilter; } - SkImageFilter* setImageFilter(SkImageFilter*); - - SkAnnotation* getAnnotation() const { return fAnnotation; } - SkAnnotation* setAnnotation(SkAnnotation*); + void setRasterizer(sk_sp); - /** - * Returns true if there is an annotation installed on this paint, and - * the annotation specifics no-drawing. - */ - SK_ATTR_DEPRECATED("use getAnnotation and check for non-null") - bool isNoDrawAnnotation() const { return this->getAnnotation() != NULL; } + SkImageFilter* getImageFilter() const { return fImageFilter.get(); } + void setImageFilter(sk_sp); /** * Return the paint's SkDrawLooper (if any). Does not affect the looper's * reference count. */ - SkDrawLooper* getLooper() const { return fLooper; } - + SkDrawLooper* getDrawLooper() const { return fDrawLooper.get(); } + SkDrawLooper* getLooper() const { return fDrawLooper.get(); } /** * Set or clear the looper object. *

* Pass NULL to clear any previous looper. - * As a convenience, the parameter passed is also returned. * If a previous looper exists in the paint, its reference count is * decremented. If looper is not NULL, its reference count is * incremented. * @param looper May be NULL. The new looper to be installed in the paint. - * @return looper */ - SkDrawLooper* setLooper(SkDrawLooper* looper); + void setDrawLooper(sk_sp); + + void setLooper(sk_sp); enum Align { kLeft_Align, @@ -673,7 +636,7 @@ class SK_API SkPaint { /** Return the paint's Align value for drawing text. @return the paint's Align value for drawing text. */ - Align getTextAlign() const { return (Align)fTextAlign; } + Align getTextAlign() const { return (Align)fBitfields.fTextAlign; } /** Set the paint's text alignment. @param align set the paint's Align value for drawing text. @@ -726,22 +689,67 @@ class SK_API SkPaint { kGlyphID_TextEncoding //!< the text parameters are glyph indices }; - TextEncoding getTextEncoding() const { return (TextEncoding)fTextEncoding; } + TextEncoding getTextEncoding() const { + return (TextEncoding)fBitfields.fTextEncoding; + } void setTextEncoding(TextEncoding encoding); struct FontMetrics { + /** Flags which indicate the confidence level of various metrics. + A set flag indicates that the metric may be trusted. + */ + enum FontMetricsFlags { + kUnderlineThinknessIsValid_Flag = 1 << 0, + kUnderlinePositionIsValid_Flag = 1 << 1, + }; + + uint32_t fFlags; //!< Bit field to identify which values are unknown SkScalar fTop; //!< The greatest distance above the baseline for any glyph (will be <= 0) SkScalar fAscent; //!< The recommended distance above the baseline (will be <= 0) SkScalar fDescent; //!< The recommended distance below the baseline (will be >= 0) SkScalar fBottom; //!< The greatest distance below the baseline for any glyph (will be >= 0) SkScalar fLeading; //!< The recommended distance to add between lines of text (will be >= 0) - SkScalar fAvgCharWidth; //!< the average charactor width (>= 0) - SkScalar fMaxCharWidth; //!< the max charactor width (>= 0) + SkScalar fAvgCharWidth; //!< the average character width (>= 0) + SkScalar fMaxCharWidth; //!< the max character width (>= 0) SkScalar fXMin; //!< The minimum bounding box x value for all glyphs SkScalar fXMax; //!< The maximum bounding box x value for all glyphs SkScalar fXHeight; //!< The height of an 'x' in px, or 0 if no 'x' in face SkScalar fCapHeight; //!< The cap height (> 0), or 0 if cannot be determined. + SkScalar fUnderlineThickness; //!< underline thickness, or 0 if cannot be determined + + /** Underline Position - position of the top of the Underline stroke + relative to the baseline, this can have following values + - Negative - means underline should be drawn above baseline. + - Positive - means below baseline. + - Zero - mean underline should be drawn on baseline. + */ + SkScalar fUnderlinePosition; //!< underline position, or 0 if cannot be determined + + /** If the fontmetrics has a valid underlinethickness, return true, and set the + thickness param to that value. If it doesn't return false and ignore the + thickness param. + */ + bool hasUnderlineThickness(SkScalar* thickness) const { + if (SkToBool(fFlags & kUnderlineThinknessIsValid_Flag)) { + *thickness = fUnderlineThickness; + return true; + } + return false; + } + + /** If the fontmetrics has a valid underlineposition, return true, and set the + thickness param to that value. If it doesn't return false and ignore the + thickness param. + */ + bool hasUnderlinePosition(SkScalar* position) const { + if (SkToBool(fFlags & kUnderlinePositionIsValid_Flag)) { + *position = fUnderlinePosition; + return true; + } + return false; + } + }; /** Return the recommend spacing between lines (which will be @@ -767,7 +775,7 @@ class SK_API SkPaint { is returned. */ int textToGlyphs(const void* text, size_t byteLength, - uint16_t glyphs[]) const; + SkGlyphID glyphs[]) const; /** Return true if all of the specified text has a corresponding non-zero glyph ID. If any of the code-points in the text are not supported in @@ -782,8 +790,7 @@ class SK_API SkPaint { to zero. Note: this does not look at the text-encoding setting in the paint, only at the typeface. */ - void glyphsToUnichars(const uint16_t glyphs[], int count, - SkUnichar text[]) const; + void glyphsToUnichars(const SkGlyphID glyphs[], int count, SkUnichar text[]) const; /** Return the number of drawable units in the specified text buffer. This looks at the current TextEncoding field of the paint. If you also @@ -802,12 +809,9 @@ class SK_API SkPaint { * @param length Number of bytes of text to measure * @param bounds If not NULL, returns the bounds of the text, * relative to (0, 0). - * @param scale If not 0, return width as if the canvas were scaled - * by this value * @return The advance width of the text */ - SkScalar measureText(const void* text, size_t length, - SkRect* bounds, SkScalar scale = 0) const; + SkScalar measureText(const void* text, size_t length, SkRect* bounds) const; /** Return the width of the text. This will return the vertical measure * if isVerticalText() is true, in which case the returned value should @@ -818,22 +822,9 @@ class SK_API SkPaint { * @return The advance width of the text */ SkScalar measureText(const void* text, size_t length) const { - return this->measureText(text, length, NULL, 0); + return this->measureText(text, length, NULL); } - /** Specify the direction the text buffer should be processed in breakText() - */ - enum TextBufferDirection { - /** When measuring text for breakText(), begin at the start of the text - buffer and proceed forward through the data. This is the default. - */ - kForward_TextBufferDirection, - /** When measuring text for breakText(), begin at the end of the text - buffer and proceed backwards through the data. - */ - kBackward_TextBufferDirection - }; - /** Return the number of bytes of text that were measured. If * isVerticalText() is true, then the vertical advances are used for * the measurement. @@ -844,15 +835,11 @@ class SK_API SkPaint { * widths are <= maxWidth are measured. * @param measuredWidth Optional. If non-null, this returns the actual * width of the measured text. - * @param tbd Optional. The direction the text buffer should be - * traversed during measuring. * @return The number of bytes of text that were measured. Will be * <= length. */ size_t breakText(const void* text, size_t length, SkScalar maxWidth, - SkScalar* measuredWidth = NULL, - TextBufferDirection tbd = kForward_TextBufferDirection) - const; + SkScalar* measuredWidth = NULL) const; /** Return the advances for the text. These will be vertical advances if * isVerticalText() returns true. @@ -870,32 +857,108 @@ class SK_API SkPaint { SkRect bounds[] = NULL) const; /** Return the path (outline) for the specified text. - Note: just like SkCanvas::drawText, this will respect the Align setting - in the paint. - */ + * Note: just like SkCanvas::drawText, this will respect the Align setting + * in the paint. + * + * @param text the text + * @param length number of bytes of text + * @param x The x-coordinate of the origin of the text. + * @param y The y-coordinate of the origin of the text. + * @param path The outline of the text. + */ void getTextPath(const void* text, size_t length, SkScalar x, SkScalar y, SkPath* path) const; + /** Return the path (outline) for the specified text. + * Note: just like SkCanvas::drawText, this will respect the Align setting + * in the paint. + * + * @param text the text + * @param length number of bytes of text + * @param pos array of positions, used to position each character + * @param path The outline of the text. + */ void getPosTextPath(const void* text, size_t length, const SkPoint pos[], SkPath* path) const; -#ifdef SK_BUILD_FOR_ANDROID - const SkGlyph& getUnicharMetrics(SkUnichar, const SkMatrix*); - const SkGlyph& getGlyphMetrics(uint16_t, const SkMatrix*); - const void* findImage(const SkGlyph&, const SkMatrix*); - - uint32_t getGenerationID() const; - void setGenerationID(uint32_t generationID); - - /** Returns the base glyph count for the strike associated with this paint - */ - unsigned getBaseGlyphCount(SkUnichar text) const; + /** Return the number of intervals that intersect the intercept along the axis of the advance. + * The return count is zero or a multiple of two, and is at most the number of glyphs * 2 in + * the string. The caller may pass nullptr for intervals to determine the size of the interval + * array, or may conservatively pre-allocate an array with length * 2 entries. The computed + * intervals are cached by glyph to improve performance for multiple calls. + * This permits constructing an underline that skips the descenders. + * + * @param text the text + * @param length number of bytes of text + * @param x The x-coordinate of the origin of the text. + * @param y The y-coordinate of the origin of the text. + * @param bounds The lower and upper line parallel to the advance. + * @param array If not null, the found intersections. + * + * @return The number of intersections, which may be zero. + */ + int getTextIntercepts(const void* text, size_t length, SkScalar x, SkScalar y, + const SkScalar bounds[2], SkScalar* intervals) const; + + /** Return the number of intervals that intersect the intercept along the axis of the advance. + * The return count is zero or a multiple of two, and is at most the number of glyphs * 2 in + * string. The caller may pass nullptr for intervals to determine the size of the interval + * array, or may conservatively pre-allocate an array with length * 2 entries. The computed + * intervals are cached by glyph to improve performance for multiple calls. + * This permits constructing an underline that skips the descenders. + * + * @param text the text + * @param length number of bytes of text + * @param pos array of positions, used to position each character + * @param bounds The lower and upper line parallel to the advance. + * @param array If not null, the glyph bounds contained by the advance parallel lines. + * + * @return The number of intersections, which may be zero. + */ + int getPosTextIntercepts(const void* text, size_t length, const SkPoint pos[], + const SkScalar bounds[2], SkScalar* intervals) const; + + /** Return the number of intervals that intersect the intercept along the axis of the advance. + * The return count is zero or a multiple of two, and is at most the number of glyphs * 2 in + * string. The caller may pass nullptr for intervals to determine the size of the interval + * array, or may conservatively pre-allocate an array with length * 2 entries. The computed + * intervals are cached by glyph to improve performance for multiple calls. + * This permits constructing an underline that skips the descenders. + * + * @param text The text. + * @param length Number of bytes of text. + * @param xpos Array of x-positions, used to position each character. + * @param constY The shared Y coordinate for all of the positions. + * @param bounds The lower and upper line parallel to the advance. + * @param array If not null, the glyph bounds contained by the advance parallel lines. + * + * @return The number of intersections, which may be zero. + */ + int getPosTextHIntercepts(const void* text, size_t length, const SkScalar xpos[], + SkScalar constY, const SkScalar bounds[2], SkScalar* intervals) const; + + /** Return the number of intervals that intersect the intercept along the axis of the advance. + * The return count is zero or a multiple of two, and is at most the number of glyphs * 2 in + * text blob. The caller may pass nullptr for intervals to determine the size of the interval + * array. The computed intervals are cached by glyph to improve performance for multiple calls. + * This permits constructing an underline that skips the descenders. + * + * @param blob The text blob. + * @param bounds The lower and upper line parallel to the advance. + * @param array If not null, the glyph bounds contained by the advance parallel lines. + * + * @return The number of intersections, which may be zero. + */ + int getTextBlobIntercepts(const SkTextBlob* blob, const SkScalar bounds[2], + SkScalar* intervals) const; - const SkPaintOptionsAndroid& getPaintOptionsAndroid() const { - return fPaintOptionsAndroid; - } - void setPaintOptionsAndroid(const SkPaintOptionsAndroid& options); -#endif + /** + * Return a rectangle that represents the union of the bounds of all + * of the glyphs, but each one positioned at (0,0). This may be conservatively large, and + * will not take into account any hinting, but will respect any text-scale-x or text-skew-x + * on this paint. + */ + SkRect getFontBounds() const; // returns true if the paint's settings (e.g. xfermode + alpha) resolve to // mean that we need not draw at all (e.g. SrcOver + 0-alpha) @@ -908,12 +971,7 @@ class SK_API SkPaint { bounds (i.e. there is nothing complex like a patheffect that would make the bounds computation expensive. */ - bool canComputeFastBounds() const { - if (this->getLooper()) { - return this->getLooper()->canComputeFastBounds(*this); - } - return !this->getRasterizer(); - } + bool canComputeFastBounds() const; /** Only call this if canComputeFastBounds() returned true. This takes a raw rectangle (the raw bounds of a shape), and adjusts it for stylistic @@ -943,6 +1001,7 @@ class SK_API SkPaint { uintptr_t effects = reinterpret_cast(this->getLooper()); effects |= reinterpret_cast(this->getMaskFilter()); effects |= reinterpret_cast(this->getPathEffect()); + effects |= reinterpret_cast(this->getImageFilter()); if (!effects) { return orig; } @@ -977,52 +1036,83 @@ class SK_API SkPaint { return SetTextMatrix(matrix, fTextSize, fTextScaleX, fTextSkewX); } - SkDEVCODE(void toString(SkString*) const;) + typedef const SkGlyph& (*GlyphCacheProc)(SkGlyphCache*, const char**); + + SK_TO_STRING_NONVIRT() private: - SkTypeface* fTypeface; + sk_sp fTypeface; + sk_sp fPathEffect; + sk_sp fShader; + sk_sp fMaskFilter; + sk_sp fColorFilter; + sk_sp fRasterizer; + sk_sp fDrawLooper; + sk_sp fImageFilter; + SkScalar fTextSize; SkScalar fTextScaleX; SkScalar fTextSkewX; - - SkPathEffect* fPathEffect; - SkShader* fShader; - SkXfermode* fXfermode; - SkMaskFilter* fMaskFilter; - SkColorFilter* fColorFilter; - SkRasterizer* fRasterizer; - SkDrawLooper* fLooper; - SkImageFilter* fImageFilter; - SkAnnotation* fAnnotation; - SkColor fColor; SkScalar fWidth; SkScalar fMiterLimit; - // all of these bitfields should add up to 32 - unsigned fFlags : 16; - unsigned fTextAlign : 2; - unsigned fCapType : 2; - unsigned fJoinType : 2; - unsigned fStyle : 2; - unsigned fTextEncoding : 2; // 3 values - unsigned fHinting : 2; - //unsigned fFreeBits : 4; - + uint32_t fBlendMode; // just need 5-6 bits + union { + struct { + // all of these bitfields should add up to 32 + unsigned fFlags : 16; + unsigned fTextAlign : 2; + unsigned fCapType : 2; + unsigned fJoinType : 2; + unsigned fStyle : 2; + unsigned fTextEncoding : 2; // 3 values + unsigned fHinting : 2; + unsigned fFilterQuality : 2; + //unsigned fFreeBits : 2; + } fBitfields; + uint32_t fBitfieldsUInt; + }; - SkDrawCacheProc getDrawCacheProc() const; - SkMeasureCacheProc getMeasureCacheProc(TextBufferDirection dir, - bool needFullMetrics) const; + static GlyphCacheProc GetGlyphCacheProc(TextEncoding encoding, + bool isDevKern, + bool needFullMetrics); SkScalar measure_text(SkGlyphCache*, const char* text, size_t length, int* count, SkRect* bounds) const; - SkGlyphCache* detachCache(const SkDeviceProperties* deviceProperties, const SkMatrix*) const; + enum ScalerContextFlags : uint32_t { + kNone_ScalerContextFlags = 0, - void descriptorProc(const SkDeviceProperties* deviceProperties, const SkMatrix* deviceMatrix, - void (*proc)(SkTypeface*, const SkDescriptor*, void*), - void* context, bool ignoreGamma = false) const; + kFakeGamma_ScalerContextFlag = 1 << 0, + kBoostContrast_ScalerContextFlag = 1 << 1, - static void Term(); + kFakeGammaAndBoostContrast_ScalerContextFlags = + kFakeGamma_ScalerContextFlag | kBoostContrast_ScalerContextFlag, + }; + + /* + * Allocs an SkDescriptor on the heap and return it to the caller as a refcnted + * SkData. Caller is responsible for managing the lifetime of this object. + */ + void getScalerContextDescriptor(SkScalerContextEffects*, SkAutoDescriptor*, + const SkSurfaceProps& surfaceProps, + uint32_t scalerContextFlags, const SkMatrix*) const; + + SkGlyphCache* detachCache(const SkSurfaceProps* surfaceProps, uint32_t scalerContextFlags, + const SkMatrix*) const; + + void descriptorProc(const SkSurfaceProps* surfaceProps, uint32_t scalerContextFlags, + const SkMatrix* deviceMatrix, + void (*proc)(SkTypeface*, const SkScalerContextEffects&, + const SkDescriptor*, void*), + void* context) const; + + /* + * The luminance color is used to determine which Gamma Canonical color to map to. This is + * really only used by backends which want to cache glyph masks, and need some way to know if + * they need to generate new masks based off a given color. + */ + SkColor computeLuminanceColor() const; enum { /* This is the size we use when we ask for a glyph's path. We then @@ -1051,9 +1141,6 @@ class SK_API SkPaint { static bool TooBigToUseCache(const SkMatrix& ctm, const SkMatrix& textM); - bool tooBigToUseCache() const; - bool tooBigToUseCache(const SkMatrix& ctm) const; - // Set flags/hinting/textSize up to use for drawing text as paths. // Returns scale factor to restore the original textSize, since will will // have change it to kCanonicalTextSizeForPaths. @@ -1066,21 +1153,19 @@ class SK_API SkPaint { } friend class SkAutoGlyphCache; + friend class SkAutoGlyphCacheNoGamma; friend class SkCanvas; friend class SkDraw; - friend class SkGraphics; // So Term() can be called. friend class SkPDFDevice; - friend class GrDistanceFieldTextContext; - friend class SkTextToPathIter; + friend class GrAtlasTextBlob; + friend class GrAtlasTextContext; + friend class GrStencilAndCoverTextContext; + friend class GrPathRendering; + friend class GrTextUtils; + friend class GrGLPathRendering; + friend class SkScalerContext; + friend class SkTextBaseIter; friend class SkCanonicalizePaint; - -#ifdef SK_BUILD_FOR_ANDROID - SkPaintOptionsAndroid fPaintOptionsAndroid; - - // In order for the == operator to work properly this must be the last field - // in the struct so that we can do a memcmp to this field's offset. - uint32_t fGenerationID; -#endif }; #endif diff --git a/libskia/include/core/SkPaintOptionsAndroid.h b/libskia/include/core/SkPaintOptionsAndroid.h deleted file mode 100644 index 42811f50..00000000 --- a/libskia/include/core/SkPaintOptionsAndroid.h +++ /dev/null @@ -1,131 +0,0 @@ - -/* - * Copyright 2012 The Android Open Source Project - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - - -#ifndef SkPaintOptionsAndroid_DEFINED -#define SkPaintOptionsAndroid_DEFINED - -#include "SkTypes.h" -#include "SkString.h" - -class SkFlattenableReadBuffer; -class SkFlattenableWriteBuffer; - -/** \class SkLanguage - - The SkLanguage class represents a human written language, and is used by - text draw operations to determine which glyph to draw when drawing - characters with variants (ie Han-derived characters). -*/ -class SkLanguage { -public: - SkLanguage() { } - SkLanguage(const SkString& tag) : fTag(tag) { } - SkLanguage(const char* tag) : fTag(tag) { } - SkLanguage(const char* tag, size_t len) : fTag(tag, len) { } - SkLanguage(const SkLanguage& b) : fTag(b.fTag) { } - - /** Gets a BCP 47 language identifier for this SkLanguage. - @return a BCP 47 language identifier representing this language - */ - const SkString& getTag() const { return fTag; } - - /** Performs BCP 47 fallback to return an SkLanguage one step more general. - @return an SkLanguage one step more general - */ - SkLanguage getParent() const; - - bool operator==(const SkLanguage& b) const { - return fTag == b.fTag; - } - bool operator!=(const SkLanguage& b) const { - return fTag != b.fTag; - } - SkLanguage& operator=(const SkLanguage& b) { - fTag = b.fTag; - return *this; - } - -private: - //! BCP 47 language identifier - SkString fTag; -}; - -class SkPaintOptionsAndroid { -public: - SkPaintOptionsAndroid() { - fFontVariant = kDefault_Variant; - // MM-2014-01-20: [[ RefactorGraphics ]] Use fallback fonts by default. - fUseFontFallbacks = true; - } - - SkPaintOptionsAndroid& operator=(const SkPaintOptionsAndroid& b) { - fLanguage = b.fLanguage; - fFontVariant = b.fFontVariant; - fUseFontFallbacks = b.fUseFontFallbacks; - return *this; - } - - bool operator==(const SkPaintOptionsAndroid& b) const { - return !(*this != b); - } - - bool operator!=(const SkPaintOptionsAndroid& b) const { - return fLanguage != b.fLanguage || - fFontVariant != b.fFontVariant || - fUseFontFallbacks != b.fUseFontFallbacks; - } - - void flatten(SkFlattenableWriteBuffer&) const; - void unflatten(SkFlattenableReadBuffer&); - - /** Return the paint's language value used for drawing text. - @return the paint's language value used for drawing text. - */ - const SkLanguage& getLanguage() const { return fLanguage; } - - /** Set the paint's language value used for drawing text. - @param language set the paint's language value for drawing text. - */ - void setLanguage(const SkLanguage& language) { fLanguage = language; } - void setLanguage(const char* languageTag) { fLanguage = SkLanguage(languageTag); } - - - enum FontVariant { - kDefault_Variant = 0x01, - kCompact_Variant = 0x02, - kElegant_Variant = 0x04, - kLast_Variant = kElegant_Variant, - }; - - /** Return the font variant - @return the font variant used by this paint object - */ - FontVariant getFontVariant() const { return fFontVariant; } - - /** Set the font variant - @param fontVariant set the paint's font variant for choosing fonts - */ - void setFontVariant(FontVariant fontVariant) { - SkASSERT((unsigned)fontVariant <= kLast_Variant); - fFontVariant = fontVariant; - } - - bool isUsingFontFallbacks() const { return fUseFontFallbacks; } - - void setUseFontFallbacks(bool useFontFallbacks) { - fUseFontFallbacks = useFontFallbacks; - } - -private: - SkLanguage fLanguage; - FontVariant fFontVariant; - bool fUseFontFallbacks; -}; - -#endif // #ifndef SkPaintOptionsAndroid_DEFINED diff --git a/libskia/include/core/SkPath.h b/libskia/include/core/SkPath.h index 9b3f281e..486a9932 100644 --- a/libskia/include/core/SkPath.h +++ b/libskia/include/core/SkPath.h @@ -1,4 +1,3 @@ - /* * Copyright 2006 The Android Open Source Project * @@ -6,14 +5,11 @@ * found in the LICENSE file. */ - #ifndef SkPath_DEFINED #define SkPath_DEFINED -#include "SkInstCnt.h" #include "SkMatrix.h" #include "SkPathRef.h" -#include "SkTDArray.h" #include "SkRefCnt.h" class SkReader32; @@ -21,6 +17,7 @@ class SkWriter32; class SkAutoPathBoundsUpdate; class SkString; class SkRRect; +class SkWStream; /** \class SkPath @@ -29,7 +26,12 @@ class SkRRect; */ class SK_API SkPath { public: - SK_DECLARE_INST_COUNT_ROOT(SkPath); + enum Direction { + /** clockwise direction for adding closed contours */ + kCW_Direction, + /** counter-clockwise direction for adding closed contours */ + kCCW_Direction, + }; SkPath(); SkPath(const SkPath&); @@ -41,6 +43,32 @@ class SK_API SkPath { return !(a == b); } + /** Return true if the paths contain an equal array of verbs and weights. Paths + * with equal verb counts can be readily interpolated. If the paths contain one + * or more conics, the conics' weights must also match. + * + * @param compare The path to compare. + * + * @return true if the paths have the same verbs and weights. + */ + bool isInterpolatable(const SkPath& compare) const; + + /** Interpolate between two paths with same-sized point arrays. + * The out path contains the verbs and weights of this path. + * The out points are a weighted average of this path and the ending path. + * + * @param ending The path to interpolate between. + * @param weight The weight, from 0 to 1. The output points are set to + * (this->points * weight) + ending->points * (1 - weight). + * @return true if the paths could be interpolated. + */ + bool interpolate(const SkPath& ending, SkScalar weight, SkPath* out) const; + +#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK + /** Returns true if the caller is the only owner of the underlying path data */ + bool unique() const { return fPathRef->unique(); } +#endif + enum FillType { /** Specifies that "inside" is computed by a non-zero sum of signed edge crossings @@ -145,13 +173,45 @@ class SK_API SkPath { * * @param rect returns the bounding rect of this oval. It's a circle * if the height and width are the same. - * + * @param dir is the oval CCW (or CW if false). + * @param start indicates where the contour starts on the oval (see + * SkPath::addOval for intepretation of the index). * @return true if this path is an oval. * Tracking whether a path is an oval is considered an * optimization for performance and so some paths that are in * fact ovals can report false. */ - bool isOval(SkRect* rect) const { return fPathRef->isOval(rect); } + bool isOval(SkRect* rect, Direction* dir = nullptr, + unsigned* start = nullptr) const { + bool isCCW = false; + bool result = fPathRef->isOval(rect, &isCCW, start); + if (dir && result) { + *dir = isCCW ? kCCW_Direction : kCW_Direction; + } + return result; + } + + /** Returns true if the path is a round rect. + * + * @param rrect Returns the bounding rect and radii of this round rect. + * @param dir is the rrect CCW (or CW if false). + * @param start indicates where the contour starts on the rrect (see + * SkPath::addRRect for intepretation of the index). + * + * @return true if this path is a round rect. + * Tracking whether a path is a round rect is considered an + * optimization for performance and so some paths that are in + * fact round rects can report false. + */ + bool isRRect(SkRRect* rrect, Direction* dir = nullptr, + unsigned* start = nullptr) const { + bool isCCW = false; + bool result = fPathRef->isRRect(rrect, &isCCW, start); + if (dir && result) { + *dir = isCCW ? kCCW_Direction : kCW_Direction; + } + return result; + } /** Clear any lines and curves from the path, making it empty. This frees up internal storage associated with those segments. @@ -175,6 +235,10 @@ class SK_API SkPath { return 0 == fPathRef->countVerbs(); } + /** Return true if the last contour of this path ends with a close verb. + */ + bool isLastContourClosed() const; + /** * Returns true if all of the points in this path are finite, meaning there * are no infinities and no NaNs. @@ -184,12 +248,29 @@ class SK_API SkPath { return fPathRef->isFinite(); } + /** Returns true if the path is volatile (i.e. should not be cached by devices.) + */ + bool isVolatile() const { + return SkToBool(fIsVolatile); + } + + /** Specify whether this path is volatile. Paths are not volatile by + default. Temporary paths that are discarded or modified after use should be + marked as volatile. This provides a hint to the device that the path + should not be cached. Providing this hint when appropriate can + improve performance by avoiding unnecessary overhead and resource + consumption on the device. + */ + void setIsVolatile(bool isVolatile) { + fIsVolatile = isVolatile; + } + /** Test a line for zero length @return true if the line is of zero length; otherwise false. */ - static bool IsLineDegenerate(const SkPoint& p1, const SkPoint& p2) { - return p1.equalsWithinTolerance(p2); + static bool IsLineDegenerate(const SkPoint& p1, const SkPoint& p2, bool exact) { + return exact ? p1 == p2 : p1.equalsWithinTolerance(p2); } /** Test a quad for zero length @@ -197,8 +278,8 @@ class SK_API SkPath { @return true if the quad is of zero length; otherwise false. */ static bool IsQuadDegenerate(const SkPoint& p1, const SkPoint& p2, - const SkPoint& p3) { - return p1.equalsWithinTolerance(p2) && + const SkPoint& p3, bool exact) { + return exact ? p1 == p2 && p2 == p3 : p1.equalsWithinTolerance(p2) && p2.equalsWithinTolerance(p3); } @@ -207,8 +288,8 @@ class SK_API SkPath { @return true if the cubic is of zero length; otherwise false. */ static bool IsCubicDegenerate(const SkPoint& p1, const SkPoint& p2, - const SkPoint& p3, const SkPoint& p4) { - return p1.equalsWithinTolerance(p2) && + const SkPoint& p3, const SkPoint& p4, bool exact) { + return exact ? p1 == p2 && p2 == p3 && p3 == p4 : p1.equalsWithinTolerance(p2) && p2.equalsWithinTolerance(p3) && p3.equalsWithinTolerance(p4); } @@ -221,16 +302,6 @@ class SK_API SkPath { */ bool isLine(SkPoint line[2]) const; - /** Returns true if the path specifies a rectangle. If so, and if rect is - not null, set rect to the bounds of the path. If the path does not - specify a rectangle, return false and ignore rect. - - @param rect If not null, returns the bounds of the path if it specifies - a rectangle - @return true if the path specifies a rectangle - */ - bool isRect(SkRect* rect) const; - /** Return the number of points in the path */ int countPoints() const; @@ -265,10 +336,12 @@ class SK_API SkPath { //! Swap contents of this and other. Guaranteed not to throw void swap(SkPath& other); - /** Returns the bounds of the path's points. If the path contains 0 or 1 - points, the bounds is set to (0,0,0,0), and isEmpty() will return true. - Note: this bounds may be larger than the actual shape, since curves - do not extend as far as their control points. + /** + * Returns the bounds of the path's points. If the path contains zero points/verbs, this + * will return the "empty" rect [0, 0, 0, 0]. + * Note: this bounds may be larger than the actual shape, since curves + * do not extend as far as their control points. Additionally this bound encompases all points, + * even isolated moveTos either preceeding or following the last non-degenerate contour. */ const SkRect& getBounds() const { return fPathRef->getBounds(); @@ -449,26 +522,23 @@ class SK_API SkPath { void rCubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2, SkScalar x3, SkScalar y3); - /** Append the specified arc to the path as a new contour. If the start of - the path is different from the path's current last point, then an - automatic lineTo() is added to connect the current contour to the start - of the arc. However, if the path is empty, then we call moveTo() with - the first point of the arc. The sweep angle is treated mod 360. - - @param oval The bounding oval defining the shape and size of the arc - @param startAngle Starting angle (in degrees) where the arc begins - @param sweepAngle Sweep angle (in degrees) measured clockwise. This is - treated mod 360. - @param forceMoveTo If true, always begin a new contour with the arc - */ - void arcTo(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle, - bool forceMoveTo); + /** + * Append the specified arc to the path. If the start of the arc is different from the path's + * current last point, then an automatic lineTo() is added to connect the current contour + * to the start of the arc. However, if the path is empty, then we call moveTo() with + * the first point of the arc. The sweep angle is treated mod 360. + * + * @param oval The bounding oval defining the shape and size of the arc + * @param startAngle Starting angle (in degrees) where the arc begins + * @param sweepAngle Sweep angle (in degrees) measured clockwise. This is treated mod 360. + * @param forceMoveTo If true, always begin a new contour with the arc + */ + void arcTo(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle, bool forceMoveTo); - /** Append a line and arc to the current path. This is the same as the - PostScript call "arct". - */ - void arcTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2, - SkScalar radius); + /** + * Append a line and arc to the current path. This is the same as the PostScript call "arct". + */ + void arcTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2, SkScalar radius); /** Append a line and arc to the current path. This is the same as the PostScript call "arct". @@ -477,31 +547,55 @@ class SK_API SkPath { this->arcTo(p1.fX, p1.fY, p2.fX, p2.fY, radius); } - /** Close the current contour. If the current point is not equal to the - first point of the contour, a line segment is automatically added. - */ - void close(); - - enum Direction { - /** Direction either has not been or could not be computed */ - kUnknown_Direction, - /** clockwise direction for adding closed contours */ - kCW_Direction, - /** counter-clockwise direction for adding closed contours */ - kCCW_Direction, + enum ArcSize { + /** the smaller of the two possible SVG arcs. */ + kSmall_ArcSize, + /** the larger of the two possible SVG arcs. */ + kLarge_ArcSize, }; /** - * Return the opposite of the specified direction. kUnknown is its own - * opposite. + * Append an elliptical arc from the current point in the format used by SVG. + * The center of the ellipse is computed to satisfy the constraints below. + * + * @param rx,ry The radii in the x and y directions respectively. + * @param xAxisRotate The angle in degrees relative to the x-axis. + * @param largeArc Determines whether the smallest or largest arc possible + * is drawn. + * @param sweep Determines if the arc should be swept in an anti-clockwise or + * clockwise direction. Note that this enum value is opposite the SVG + * arc sweep value. + * @param x,y The destination coordinates. */ - static Direction OppositeDirection(Direction dir) { - static const Direction gOppositeDir[] = { - kUnknown_Direction, kCCW_Direction, kCW_Direction - }; - return gOppositeDir[dir]; + void arcTo(SkScalar rx, SkScalar ry, SkScalar xAxisRotate, ArcSize largeArc, + Direction sweep, SkScalar x, SkScalar y); + + void arcTo(const SkPoint r, SkScalar xAxisRotate, ArcSize largeArc, Direction sweep, + const SkPoint xy) { + this->arcTo(r.fX, r.fY, xAxisRotate, largeArc, sweep, xy.fX, xy.fY); } + /** Same as arcTo format used by SVG, but the destination coordinate is relative to the + * last point on this contour. If there is no previous point, then a + * moveTo(0,0) is inserted automatically. + * + * @param rx,ry The radii in the x and y directions respectively. + * @param xAxisRotate The angle in degrees relative to the x-axis. + * @param largeArc Determines whether the smallest or largest arc possible + * is drawn. + * @param sweep Determines if the arc should be swept in an anti-clockwise or + * clockwise direction. Note that this enum value is opposite the SVG + * arc sweep value. + * @param dx,dy The destination coordinates relative to the last point. + */ + void rArcTo(SkScalar rx, SkScalar ry, SkScalar xAxisRotate, ArcSize largeArc, + Direction sweep, SkScalar dx, SkScalar dy); + + /** Close the current contour. If the current point is not equal to the + first point of the contour, a line segment is automatically added. + */ + void close(); + /** * Returns whether or not a fill type is inverted * @@ -511,10 +605,10 @@ class SK_API SkPath { * kInverseEvenOdd_FillType -> true */ static bool IsInverseFillType(FillType fill) { - SK_COMPILE_ASSERT(0 == kWinding_FillType, fill_type_mismatch); - SK_COMPILE_ASSERT(1 == kEvenOdd_FillType, fill_type_mismatch); - SK_COMPILE_ASSERT(2 == kInverseWinding_FillType, fill_type_mismatch); - SK_COMPILE_ASSERT(3 == kInverseEvenOdd_FillType, fill_type_mismatch); + static_assert(0 == kWinding_FillType, "fill_type_mismatch"); + static_assert(1 == kEvenOdd_FillType, "fill_type_mismatch"); + static_assert(2 == kInverseWinding_FillType, "fill_type_mismatch"); + static_assert(3 == kInverseEvenOdd_FillType, "fill_type_mismatch"); return (fill & 2) != 0; } @@ -527,46 +621,39 @@ class SK_API SkPath { * kInverseEvenOdd_FillType -> kEvenOdd_FillType */ static FillType ConvertToNonInverseFillType(FillType fill) { - SK_COMPILE_ASSERT(0 == kWinding_FillType, fill_type_mismatch); - SK_COMPILE_ASSERT(1 == kEvenOdd_FillType, fill_type_mismatch); - SK_COMPILE_ASSERT(2 == kInverseWinding_FillType, fill_type_mismatch); - SK_COMPILE_ASSERT(3 == kInverseEvenOdd_FillType, fill_type_mismatch); + static_assert(0 == kWinding_FillType, "fill_type_mismatch"); + static_assert(1 == kEvenOdd_FillType, "fill_type_mismatch"); + static_assert(2 == kInverseWinding_FillType, "fill_type_mismatch"); + static_assert(3 == kInverseEvenOdd_FillType, "fill_type_mismatch"); return (FillType)(fill & 1); } /** - * Tries to quickly compute the direction of the first non-degenerate - * contour. If it can be computed, return true and set dir to that - * direction. If it cannot be (quickly) determined, return false and ignore - * the dir parameter. If the direction was determined, it is cached to make - * subsequent calls return quickly. + * Chop a conic into N quads, stored continguously in pts[], where + * N = 1 << pow2. The amount of storage needed is (1 + 2 * N) */ - bool cheapComputeDirection(Direction* dir) const; + static int ConvertConicToQuads(const SkPoint& p0, const SkPoint& p1, const SkPoint& p2, + SkScalar w, SkPoint pts[], int pow2); /** - * Returns true if the path's direction can be computed via - * cheapComputDirection() and if that computed direction matches the - * specified direction. If dir is kUnknown, returns true if the direction - * cannot be computed. + * Returns true if the path specifies a rectangle. + * + * If this returns false, then all output parameters are ignored, and left + * unchanged. If this returns true, then each of the output parameters + * are checked for NULL. If they are not, they return their value. + * + * @param rect If not null, set to the bounds of the rectangle. + * Note : this bounds may be smaller than the path's bounds, since it is just + * the bounds of the "drawable" parts of the path. e.g. a trailing MoveTo would + * be ignored in this rect, but not by the path's bounds + * @param isClosed If not null, set to true if the path is closed + * @param direction If not null, set to the rectangle's direction + * @return true if the path specifies a rectangle */ - bool cheapIsDirection(Direction dir) const { - Direction computedDir = kUnknown_Direction; - (void)this->cheapComputeDirection(&computedDir); - return computedDir == dir; - } - - /** Returns true if the path specifies a rectangle. If so, and if isClosed is - not null, set isClosed to true if the path is closed. Also, if returning true - and direction is not null, return the rect direction. If the path does not - specify a rectangle, return false and ignore isClosed and direction. - - @param isClosed If not null, set to true if the path is closed - @param direction If not null, set to the rectangle's direction - @return true if the path specifies a rectangle - */ - bool isRect(bool* isClosed, Direction* direction) const; + bool isRect(SkRect* rect, bool* isClosed = NULL, Direction* direction = NULL) const; - /** Returns true if the path specifies a pair of nested rectangles. If so, and if + /** Returns true if the path specifies a pair of nested rectangles, or would draw a + pair of nested rectangles when filled. If so, and if rect is not null, set rect[0] to the outer rectangle and rect[1] to the inner rectangle. If so, and dirs is not null, set dirs[0] to the direction of the outer rectangle and dirs[1] to the direction of the inner rectangle. If @@ -577,16 +664,32 @@ class SK_API SkPath { @param dirs If not null, returns the direction of the rects @return true if the path describes a pair of nested rectangles */ - bool isNestedRects(SkRect rect[2], Direction dirs[2] = NULL) const; + bool isNestedFillRects(SkRect rect[2], Direction dirs[2] = NULL) const; /** * Add a closed rectangle contour to the path * @param rect The rectangle to add as a closed contour to the path - * @param dir The direction to wind the rectangle's contour. Cannot be - * kUnknown_Direction. + * @param dir The direction to wind the rectangle's contour. + * + * Note: the contour initial point index is 0 (as defined below). */ void addRect(const SkRect& rect, Direction dir = kCW_Direction); + /** + * Add a closed rectangle contour to the path + * @param rect The rectangle to add as a closed contour to the path + * @param dir The direction to wind the rectangle's contour. + * @param start Initial point of the contour (initial moveTo), expressed as + * a corner index, starting in the upper-left position, clock-wise: + * + * 0 1 + * *-------* + * | | + * *-------* + * 3 2 + */ + void addRect(const SkRect& rect, Direction dir, unsigned start); + /** * Add a closed rectangle contour to the path * @@ -598,8 +701,9 @@ class SK_API SkPath { * to the path * @param bottom The bottom of a rectangle to add as a closed contour to * the path - * @param dir The direction to wind the rectangle's contour. Cannot be - * kUnknown_Direction. + * @param dir The direction to wind the rectangle's contour. + * + * Note: the contour initial point index is 0 (as defined above). */ void addRect(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom, Direction dir = kCW_Direction); @@ -608,13 +712,34 @@ class SK_API SkPath { * Add a closed oval contour to the path * * @param oval The bounding oval to add as a closed contour to the path - * @param dir The direction to wind the oval's contour. Cannot be - * kUnknown_Direction. + * @param dir The direction to wind the oval's contour. + * + * Note: the contour initial point index is 1 (as defined below). */ void addOval(const SkRect& oval, Direction dir = kCW_Direction); /** - * Add a closed circle contour to the path + * Add a closed oval contour to the path + * + * @param oval The bounding oval to add as a closed contour to the path + * @param dir The direction to wind the oval's contour. + * @param start Initial point of the contour (initial moveTo), expressed + * as an ellipse vertex index, starting at the top, clock-wise + * (90/0/270/180deg order): + * + * 0 + * -*- + * | | + * 3 * * 1 + * | | + * -*- + * 2 + */ + void addOval(const SkRect& oval, Direction dir, unsigned start); + + /** + * Add a closed circle contour to the path. The circle contour begins at + * the right-most point (as though 1 were passed to addOval's 'start' param). * * @param x The x-coordinate of the center of a circle to add as a * closed contour to the path @@ -622,8 +747,7 @@ class SK_API SkPath { * closed contour to the path * @param radius The radius of a circle to add as a closed contour to the * path - * @param dir The direction to wind the circle's contour. Cannot be - * kUnknown_Direction. + * @param dir The direction to wind the circle's contour. */ void addCircle(SkScalar x, SkScalar y, SkScalar radius, Direction dir = kCW_Direction); @@ -641,8 +765,7 @@ class SK_API SkPath { * @param rect The bounds of a round-rectangle to add as a closed contour * @param rx The x-radius of the rounded corners on the round-rectangle * @param ry The y-radius of the rounded corners on the round-rectangle - * @param dir The direction to wind the rectangle's contour. Cannot be - * kUnknown_Direction. + * @param dir The direction to wind the rectangle's contour. */ void addRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry, Direction dir = kCW_Direction); @@ -653,8 +776,7 @@ class SK_API SkPath { * bottom-right, bottom-left. * @param rect The bounds of a round-rectangle to add as a closed contour * @param radii Array of 8 scalars, 4 [X,Y] pairs for each corner - * @param dir The direction to wind the rectangle's contour. Cannot be - * kUnknown_Direction. + * @param dir The direction to wind the rectangle's contour. * Note: The radii here now go through the same constraint handling as the * SkRRect radii (i.e., either radii at a corner being 0 implies a * sqaure corner and oversized radii are proportionally scaled down). @@ -665,11 +787,31 @@ class SK_API SkPath { /** * Add an SkRRect contour to the path * @param rrect The rounded rect to add as a closed contour - * @param dir The winding direction for the new contour. Cannot be - * kUnknown_Direction. + * @param dir The winding direction for the new contour. + * + * Note: the contour initial point index is either 6 (for dir == kCW_Direction) + * or 7 (for dir == kCCW_Direction), as defined below. + * */ void addRRect(const SkRRect& rrect, Direction dir = kCW_Direction); + /** + * Add an SkRRect contour to the path + * @param rrect The rounded rect to add as a closed contour + * @param dir The winding direction for the new contour. + * @param start Initial point of the contour (initial moveTo), expressed as + * an index of the radii minor/major points, ordered clock-wise: + * + * 0 1 + * *----* + * 7 * * 2 + * | | + * 6 * * 3 + * *----* + * 5 4 + */ + void addRRect(const SkRRect& rrect, Direction dir, unsigned start); + /** * Add a new contour made of just lines. This is just a fast version of * the following: @@ -683,25 +825,41 @@ class SK_API SkPath { */ void addPoly(const SkPoint pts[], int count, bool close); + enum AddPathMode { + /** Source path contours are added as new contours. + */ + kAppend_AddPathMode, + /** Path is added by extending the last contour of the destination path + with the first contour of the source path. If the last contour of + the destination path is closed, then it will not be extended. + Instead, the start of source path will be extended by a straight + line to the end point of the destination path. + */ + kExtend_AddPathMode + }; + /** Add a copy of src to the path, offset by (dx,dy) @param src The path to add as a new contour @param dx The amount to translate the path in X as it is added @param dx The amount to translate the path in Y as it is added */ - void addPath(const SkPath& src, SkScalar dx, SkScalar dy); + void addPath(const SkPath& src, SkScalar dx, SkScalar dy, + AddPathMode mode = kAppend_AddPathMode); /** Add a copy of src to the path */ - void addPath(const SkPath& src) { + void addPath(const SkPath& src, AddPathMode mode = kAppend_AddPathMode) { SkMatrix m; m.reset(); - this->addPath(src, m); + this->addPath(src, m, mode); } /** Add a copy of src to the path, transformed by matrix @param src The path to add as a new contour + @param matrix Transform applied to src + @param mode Determines how path is added */ - void addPath(const SkPath& src, const SkMatrix& matrix); + void addPath(const SkPath& src, const SkMatrix& matrix, AddPathMode mode = kAppend_AddPathMode); /** * Same as addPath(), but reverses the src input @@ -786,7 +944,7 @@ class SK_API SkPath { kQuad_Verb, //!< iter.next returns 3 points kConic_Verb, //!< iter.next returns 3 points + iter.conicWeight() kCubic_Verb, //!< iter.next returns 4 points - kClose_Verb, //!< iter.next returns 1 point (contour's moveTo pt) + kClose_Verb, //!< iter.next returns 0 points kDone_Verb, //!< iter.next returns 0 points }; @@ -812,11 +970,15 @@ class SK_API SkPath { @param pts The points representing the current verb and/or segment @param doConsumeDegerates If true, first scan for segments that are deemed degenerate (too short) and skip those. + @param exact if doConsumeDegenerates is true and exact is true, skip only + degenerate elements with lengths exactly equal to zero. If exact + is false, skip degenerate elements with lengths close to zero. If + doConsumeDegenerates is false, exact has no effect. @return The verb for the current segment */ - Verb next(SkPoint pts[4], bool doConsumeDegerates = true) { + Verb next(SkPoint pts[4], bool doConsumeDegerates = true, bool exact = false) { if (doConsumeDegerates) { - this->consumeDegenerateSegments(); + this->consumeDegenerateSegments(exact); } return this->doNext(pts); } @@ -856,7 +1018,7 @@ class SK_API SkPath { inline const SkPoint& cons_moveTo(); Verb autoClose(SkPoint pts[2]); - void consumeDegenerateSegments(); + void consumeDegenerateSegments(bool exact); Verb doNext(SkPoint pts[4]); }; @@ -864,10 +1026,14 @@ class SK_API SkPath { */ class SK_API RawIter { public: - RawIter(); - RawIter(const SkPath&); + RawIter() {} + RawIter(const SkPath& path) { + setPath(path); + } - void setPath(const SkPath&); + void setPath(const SkPath& path) { + fRawIter.setPathRef(*path.fPathRef.get()); + } /** Return the next verb in this iteration of the path. When all segments have been visited, return kDone_Verb. @@ -876,17 +1042,25 @@ class SK_API SkPath { This must not be NULL. @return The verb for the current segment */ - Verb next(SkPoint pts[4]); + Verb next(SkPoint pts[4]) { + return (Verb) fRawIter.next(pts); + } - SkScalar conicWeight() const { return *fConicWeights; } + /** Return what the next verb will be, but do not visit the next segment. + + @return The verb for the next segment + */ + Verb peek() const { + return (Verb) fRawIter.peek(); + } + + SkScalar conicWeight() const { + return fRawIter.conicWeight(); + } private: - const SkPoint* fPts; - const uint8_t* fVerbs; - const uint8_t* fVerbStop; - const SkScalar* fConicWeights; - SkPoint fMoveTo; - SkPoint fLastPt; + SkPathRef::Iter fRawIter; + friend class SkPath; }; /** @@ -895,8 +1069,9 @@ class SK_API SkPath { */ bool contains(SkScalar x, SkScalar y) const; - void dump(bool forceClose, const char title[] = NULL) const; + void dump(SkWStream* , bool forceClose, bool dumpAsHex) const; void dump() const; + void dumpHex() const; /** * Write the path to the buffer, and return the number of bytes written. @@ -919,43 +1094,39 @@ class SK_API SkPath { */ uint32_t getGenerationID() const; -#ifdef SK_BUILD_FOR_ANDROID +#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK static const int kPathRefGenIDBitCnt = 30; // leave room for the fill type (skbug.com/1762) - const SkPath* getSourcePath() const; - void setSourcePath(const SkPath* path); #else static const int kPathRefGenIDBitCnt = 32; #endif SkDEBUGCODE(void validate() const;) + SkDEBUGCODE(void experimentalValidateRef() const { fPathRef->validate(); } ) private: enum SerializationOffsets { -#ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V16_AND_ALL_OTHER_INSTANCES_TOO - kNewFormat_SerializationShift = 29, // requires 1 bit -#endif + // 1 free bit at 29 kUnused1_SerializationShift = 28, // 1 free bit kDirection_SerializationShift = 26, // requires 2 bits - kUnused2_SerializationShift = 25, // 1 free bit -#ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V16_AND_ALL_OTHER_INSTANCES_TOO - kOldIsOval_SerializationShift = 24, // requires 1 bit -#endif + kIsVolatile_SerializationShift = 25, // requires 1 bit + // 1 free bit at 24 kConvexity_SerializationShift = 16, // requires 8 bits kFillType_SerializationShift = 8, // requires 8 bits -#ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V16_AND_ALL_OTHER_INSTANCES_TOO - kOldSegmentMask_SerializationShift = 0 // requires 4 bits -#endif + // low-8-bits are version }; - SkAutoTUnref fPathRef; + enum SerializationVersions { + kPathPrivFirstDirection_Version = 1, + kPathPrivLastMoveToIndex_Version = 2, + kCurrent_Version = 2 + }; - int fLastMoveToIndex; - uint8_t fFillType; - mutable uint8_t fConvexity; - mutable uint8_t fDirection; -#ifdef SK_BUILD_FOR_ANDROID - const SkPath* fSourcePath; -#endif + sk_sp fPathRef; + int fLastMoveToIndex; + uint8_t fFillType; + mutable uint8_t fConvexity; + mutable SkAtomic fFirstDirection;// SkPathPriv::FirstDirection + SkBool8 fIsVolatile; /** Resets all fields other than fPathRef to their initial 'empty' values. * Assumes the caller has already emptied fPathRef. @@ -970,7 +1141,7 @@ class SK_API SkPath { void copyFields(const SkPath& that); friend class Iter; - + friend class SkPathPriv; friend class SkPathStroker; /* Append, in reverse order, the first contour of path, ignoring path's @@ -994,6 +1165,10 @@ class SK_API SkPath { bool isRectContour(bool allowPartial, int* currVerb, const SkPoint** pts, bool* isClosed, Direction* direction) const; + // called by stroker to see if all points are equal and worthy of a cap + // equivalent to a short-circuit version of getBounds().isEmpty() + bool isZeroLength() const; + /** Returns if the path can return a bound at no cost (true) or will have to perform some computation (false). */ @@ -1010,14 +1185,16 @@ class SK_API SkPath { ed.setBounds(rect); } -#ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V16_AND_ALL_OTHER_INSTANCES_TOO - friend class SkPathRef; // just for SerializationOffsets -#endif + void setPt(int index, SkScalar x, SkScalar y); + friend class SkAutoPathBoundsUpdate; friend class SkAutoDisableOvalCheck; friend class SkAutoDisableDirectionCheck; + friend class SkPathWriter; + friend class SkOpBuilder; friend class SkBench_AddPathTest; // perf test reversePathTo friend class PathTest_Private; // unit test reversePathTo + friend class ForceIsRRect_Private; // unit test isRRect }; #endif diff --git a/libskia/include/core/SkPathEffect.h b/libskia/include/core/SkPathEffect.h index ed6d93b7..ff3fa01f 100644 --- a/libskia/include/core/SkPathEffect.h +++ b/libskia/include/core/SkPathEffect.h @@ -14,10 +14,9 @@ #include "SkPath.h" #include "SkPoint.h" #include "SkRect.h" -#include "SkStrokeRec.h" -#include "SkTDArray.h" class SkPath; +class SkStrokeRec; /** \class SkPathEffect @@ -29,10 +28,6 @@ class SkPath; */ class SK_API SkPathEffect : public SkFlattenable { public: - SK_DECLARE_INST_COUNT(SkPathEffect) - - SkPathEffect() {} - /** * Given a src path (input) and a stroke-rec (input and output), apply * this effect to the src path, returning the new path in dst, and return @@ -71,7 +66,7 @@ class SK_API SkPathEffect : public SkFlattenable { fSize.set(SK_Scalar1, SK_Scalar1); // 'asPoints' needs to initialize/fill-in 'fClipRect' if it sets // the kUseClip flag - }; + } ~PointData() { delete [] fPoints; } @@ -106,10 +101,45 @@ class SK_API SkPathEffect : public SkFlattenable { const SkStrokeRec&, const SkMatrix&, const SkRect* cullR) const; + /** + * If the PathEffect can be represented as a dash pattern, asADash will return kDash_DashType + * and None otherwise. If a non NULL info is passed in, the various DashInfo will be filled + * in if the PathEffect can be a dash pattern. If passed in info has an fCount equal or + * greater to that of the effect, it will memcpy the values of the dash intervals into the + * info. Thus the general approach will be call asADash once with default info to get DashType + * and fCount. If effect can be represented as a dash pattern, allocate space for the intervals + * in info, then call asADash again with the same info and the intervals will get copied in. + */ + + enum DashType { + kNone_DashType, //!< ignores the info parameter + kDash_DashType, //!< fills in all of the info parameter + }; + + struct DashInfo { + DashInfo() : fIntervals(NULL), fCount(0), fPhase(0) {} + DashInfo(SkScalar* intervals, int32_t count, SkScalar phase) + : fIntervals(intervals), fCount(count), fPhase(phase) {} + + SkScalar* fIntervals; //!< Length of on/off intervals for dashed lines + // Even values represent ons, and odds offs + int32_t fCount; //!< Number of intervals in the dash. Should be even number + SkScalar fPhase; //!< Offset into the dashed interval pattern + // mod the sum of all intervals + }; + + virtual DashType asADash(DashInfo* info) const; + + SK_TO_STRING_PUREVIRT() SK_DEFINE_FLATTENABLE_TYPE(SkPathEffect) +#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK + /// Override for subclasses as appropriate. + virtual bool exposedInAndroidJavaAPI() const { return false; } +#endif + protected: - SkPathEffect(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {} + SkPathEffect() {} private: // illegal @@ -125,17 +155,17 @@ class SK_API SkPathEffect : public SkFlattenable { including flattening them. It does nothing in filterPath, and is only useful for managing the lifetimes of its two arguments. */ -class SkPairPathEffect : public SkPathEffect { -public: - SkPairPathEffect(SkPathEffect* pe0, SkPathEffect* pe1); - virtual ~SkPairPathEffect(); - +class SK_API SkPairPathEffect : public SkPathEffect { protected: - SkPairPathEffect(SkFlattenableReadBuffer&); - virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE; + SkPairPathEffect(sk_sp pe0, sk_sp pe1); + + void flatten(SkWriteBuffer&) const override; // these are visible to our subclasses - SkPathEffect* fPE0, *fPE1; + sk_sp fPE0; + sk_sp fPE1; + + SK_TO_STRING_OVERRIDE() private: typedef SkPathEffect INHERITED; @@ -146,23 +176,36 @@ class SkPairPathEffect : public SkPathEffect { This subclass of SkPathEffect composes its two arguments, to create a compound pathEffect. */ -class SkComposePathEffect : public SkPairPathEffect { +class SK_API SkComposePathEffect : public SkPairPathEffect { public: /** Construct a pathEffect whose effect is to apply first the inner pathEffect and the the outer pathEffect (e.g. outer(inner(path))) The reference counts for outer and inner are both incremented in the constructor, and decremented in the destructor. */ - SkComposePathEffect(SkPathEffect* outer, SkPathEffect* inner) - : INHERITED(outer, inner) {} + static sk_sp Make(sk_sp outer, sk_sp inner) { + if (!outer) { + return inner; + } + if (!inner) { + return outer; + } + return sk_sp(new SkComposePathEffect(outer, inner)); + } virtual bool filterPath(SkPath* dst, const SkPath& src, - SkStrokeRec*, const SkRect*) const SK_OVERRIDE; + SkStrokeRec*, const SkRect*) const override; + SK_TO_STRING_OVERRIDE() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkComposePathEffect) +#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK + bool exposedInAndroidJavaAPI() const override { return true; } +#endif + protected: - SkComposePathEffect(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {} + SkComposePathEffect(sk_sp outer, sk_sp inner) + : INHERITED(outer, inner) {} private: // illegal @@ -177,23 +220,36 @@ class SkComposePathEffect : public SkPairPathEffect { This subclass of SkPathEffect applies two pathEffects, one after the other. Its filterPath() returns true if either of the effects succeeded. */ -class SkSumPathEffect : public SkPairPathEffect { +class SK_API SkSumPathEffect : public SkPairPathEffect { public: /** Construct a pathEffect whose effect is to apply two effects, in sequence. (e.g. first(path) + second(path)) The reference counts for first and second are both incremented in the constructor, and decremented in the destructor. */ - SkSumPathEffect(SkPathEffect* first, SkPathEffect* second) - : INHERITED(first, second) {} + static sk_sp Make(sk_sp first, sk_sp second) { + if (!first) { + return second; + } + if (!second) { + return first; + } + return sk_sp(new SkSumPathEffect(first, second)); + } virtual bool filterPath(SkPath* dst, const SkPath& src, - SkStrokeRec*, const SkRect*) const SK_OVERRIDE; + SkStrokeRec*, const SkRect*) const override; + SK_TO_STRING_OVERRIDE() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkSumPathEffect) +#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK + bool exposedInAndroidJavaAPI() const override { return true; } +#endif + protected: - SkSumPathEffect(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {} + SkSumPathEffect(sk_sp first, sk_sp second) + : INHERITED(first, second) {} private: // illegal diff --git a/libskia/include/core/SkPathMeasure.h b/libskia/include/core/SkPathMeasure.h index bc46b4a3..1044f7ee 100644 --- a/libskia/include/core/SkPathMeasure.h +++ b/libskia/include/core/SkPathMeasure.h @@ -8,8 +8,10 @@ #ifndef SkPathMeasure_DEFINED #define SkPathMeasure_DEFINED +#include "../private/SkTDArray.h" #include "SkPath.h" -#include "SkTDArray.h" + +struct SkConic; class SK_API SkPathMeasure : SkNoncopyable { public: @@ -18,8 +20,11 @@ class SK_API SkPathMeasure : SkNoncopyable { for the lifetime of the measure object, or until setPath() is called with a different path (or null), since the measure object keeps a pointer to the path object (does not copy its data). + + resScale controls the precision of the measure. values > 1 increase the + precision (and possible slow down the computation). */ - SkPathMeasure(const SkPath& path, bool forceClosed); + SkPathMeasure(const SkPath& path, bool forceClosed, SkScalar resScale = 1); ~SkPathMeasure(); /** Reset the pathmeasure with the specified path. The path must remain valid @@ -58,7 +63,7 @@ class SK_API SkPathMeasure : SkNoncopyable { /** Given a start and stop distance, return in dst the intervening segment(s). If the segment is zero-length, return false, else return true. - startD and stopD are pinned to legal values (0..getLength()). If startD <= stopD + startD and stopD are pinned to legal values (0..getLength()). If startD > stopD then return false (and leave dst untouched). Begin the segment with a moveTo if startWithMoveTo is true */ @@ -80,6 +85,7 @@ class SK_API SkPathMeasure : SkNoncopyable { private: SkPath::Iter fIter; const SkPath* fPath; + SkScalar fTolerance; SkScalar fLength; // relative to the current contour int fFirstPtIndex; // relative to the current contour bool fIsClosed; // relative to the current contour @@ -87,9 +93,10 @@ class SK_API SkPathMeasure : SkNoncopyable { struct Segment { SkScalar fDistance; // total distance up to this point - unsigned fPtIndex : 15; // index into the fPts array - unsigned fTValue : 15; - unsigned fType : 2; + unsigned fPtIndex; // index into the fPts array + unsigned fTValue : 30; + unsigned fType : 2; // actually the enum SkSegType + // See SkPathMeasurePriv.h SkScalar getScalarT() const; }; @@ -101,9 +108,16 @@ class SK_API SkPathMeasure : SkNoncopyable { void buildSegments(); SkScalar compute_quad_segs(const SkPoint pts[3], SkScalar distance, int mint, int maxt, int ptIndex); + SkScalar compute_conic_segs(const SkConic&, SkScalar distance, + int mint, const SkPoint& minPt, + int maxt, const SkPoint& maxPt, int ptIndex); SkScalar compute_cubic_segs(const SkPoint pts[3], SkScalar distance, int mint, int maxt, int ptIndex); const Segment* distanceToSegment(SkScalar distance, SkScalar* t); + bool quad_too_curvy(const SkPoint pts[3]); + bool conic_too_curvy(const SkPoint& firstPt, const SkPoint& midTPt,const SkPoint& lastPt); + bool cheap_dist_exceeds_limit(const SkPoint& pt, SkScalar x, SkScalar y); + bool cubic_too_curvy(const SkPoint pts[4]); }; #endif diff --git a/libskia/include/core/SkPathRef.h b/libskia/include/core/SkPathRef.h index 53584207..5e6fda7d 100644 --- a/libskia/include/core/SkPathRef.h +++ b/libskia/include/core/SkPathRef.h @@ -9,11 +9,13 @@ #ifndef SkPathRef_DEFINED #define SkPathRef_DEFINED +#include "../private/SkAtomics.h" +#include "../private/SkTDArray.h" #include "SkMatrix.h" #include "SkPoint.h" +#include "SkRRect.h" #include "SkRect.h" #include "SkRefCnt.h" -#include "SkTDArray.h" #include // ptrdiff_t class SkRBuffer; @@ -24,8 +26,8 @@ class SkWBuffer; * modify the contents. To modify or append to the verbs/points wrap the SkPathRef in an * SkPathRef::Editor object. Installing the editor resets the generation ID. It also performs * copy-on-write if the SkPathRef is shared by multiple SkPaths. The caller passes the Editor's - * constructor a SkAutoTUnref, which may be updated to point to a new SkPathRef after the editor's - * constructor returns. + * constructor a pointer to a sk_sp, which may be updated to point to a new SkPathRef + * after the editor's constructor returns. * * The points and verbs are stored in a single allocation. The points are at the begining of the * allocation while the verbs are stored at end of the allocation, in reverse order. Thus the points @@ -34,13 +36,11 @@ class SkWBuffer; * logical verb or the last verb in memory). */ -class SK_API SkPathRef : public ::SkRefCnt { +class SK_API SkPathRef final : public SkNVRefCnt { public: - SK_DECLARE_INST_COUNT(SkPathRef); - class Editor { public: - Editor(SkAutoTUnref* pathRef, + Editor(sk_sp* pathRef, int incReserveVerbs = 0, int incReservePoints = 0); @@ -58,11 +58,11 @@ class SK_API SkPathRef : public ::SkRefCnt { SkPoint* atPoint(int i) { SkASSERT((unsigned) i < (unsigned) fPathRef->fPointCnt); return this->points() + i; - }; + } const SkPoint* atPoint(int i) const { SkASSERT((unsigned) i < (unsigned) fPathRef->fPointCnt); return this->points() + i; - }; + } /** * Adds the verb and allocates space for the number of points indicated by the verb. The @@ -100,7 +100,13 @@ class SK_API SkPathRef : public ::SkRefCnt { */ SkPathRef* pathRef() { return fPathRef; } - void setIsOval(bool isOval) { fPathRef->setIsOval(isOval); } + void setIsOval(bool isOval, bool isCCW, unsigned start) { + fPathRef->setIsOval(isOval, isCCW, start); + } + + void setIsRRect(bool isRRect, bool isCCW, unsigned start) { + fPathRef->setIsRRect(isRRect, isCCW, start); + } void setBounds(const SkRect& rect) { fPathRef->setBounds(rect); } @@ -108,6 +114,32 @@ class SK_API SkPathRef : public ::SkRefCnt { SkPathRef* fPathRef; }; + class SK_API Iter { + public: + Iter(); + Iter(const SkPathRef&); + + void setPathRef(const SkPathRef&); + + /** Return the next verb in this iteration of the path. When all + segments have been visited, return kDone_Verb. + + @param pts The points representing the current verb and/or segment + This must not be NULL. + @return The verb for the current segment + */ + uint8_t next(SkPoint pts[4]); + uint8_t peek() const; + + SkScalar conicWeight() const { return *fConicWeights; } + + private: + const SkPoint* fPts; + const uint8_t* fVerbs; + const uint8_t* fVerbStop; + const SkScalar* fConicWeights; + }; + public: /** * Gets a path ref with no verbs or points. @@ -136,20 +168,47 @@ class SK_API SkPathRef : public ::SkRefCnt { * * @param rect returns the bounding rect of this oval. It's a circle * if the height and width are the same. + * @param isCCW is the oval CCW (or CW if false). + * @param start indicates where the contour starts on the oval (see + * SkPath::addOval for intepretation of the index). * * @return true if this path is an oval. * Tracking whether a path is an oval is considered an * optimization for performance and so some paths that are in * fact ovals can report false. */ - bool isOval(SkRect* rect) const { - if (fIsOval && NULL != rect) { - *rect = getBounds(); + bool isOval(SkRect* rect, bool* isCCW, unsigned* start) const { + if (fIsOval) { + if (rect) { + *rect = this->getBounds(); + } + if (isCCW) { + *isCCW = SkToBool(fRRectOrOvalIsCCW); + } + if (start) { + *start = fRRectOrOvalStartIdx; + } } return SkToBool(fIsOval); } + bool isRRect(SkRRect* rrect, bool* isCCW, unsigned* start) const { + if (fIsRRect) { + if (rrect) { + *rrect = this->getRRect(); + } + if (isCCW) { + *isCCW = SkToBool(fRRectOrOvalIsCCW); + } + if (start) { + *start = fRRectOrOvalStartIdx; + } + } + return SkToBool(fIsRRect); + } + + bool hasComputedBounds() const { return !fBoundsIsDirty; } @@ -166,39 +225,25 @@ class SK_API SkPathRef : public ::SkRefCnt { return fBounds; } + SkRRect getRRect() const; + /** * Transforms a path ref by a matrix, allocating a new one only if necessary. */ - static void CreateTransformedCopy(SkAutoTUnref* dst, + static void CreateTransformedCopy(sk_sp* dst, const SkPathRef& src, const SkMatrix& matrix); - static SkPathRef* CreateFromBuffer(SkRBuffer* buffer -#ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V16_AND_ALL_OTHER_INSTANCES_TOO - , bool newFormat, int32_t oldPacked -#endif - ); + static SkPathRef* CreateFromBuffer(SkRBuffer* buffer); /** * Rollsback a path ref to zero verbs and points with the assumption that the path ref will be * repopulated with approximately the same number of verbs and points. A new path ref is created * only if necessary. */ - static void Rewind(SkAutoTUnref* pathRef); - - virtual ~SkPathRef() { - SkDEBUGCODE(this->validate();) - sk_free(fPoints); - - SkDEBUGCODE(fPoints = NULL;) - SkDEBUGCODE(fVerbs = NULL;) - SkDEBUGCODE(fVerbCnt = 0x9999999;) - SkDEBUGCODE(fPointCnt = 0xAAAAAAA;) - SkDEBUGCODE(fPointCnt = 0xBBBBBBB;) - SkDEBUGCODE(fGenerationID = 0xEEEEEEEE;) - SkDEBUGCODE(fEditorsAttached = 0x7777777;) - } + static void Rewind(sk_sp* pathRef); + ~SkPathRef(); int countPoints() const { SkDEBUGCODE(this->validate();) return fPointCnt; } int countVerbs() const { SkDEBUGCODE(this->validate();) return fVerbCnt; } int countWeights() const { SkDEBUGCODE(this->validate();) return fConicWeights.count(); } @@ -250,6 +295,8 @@ class SK_API SkPathRef : public ::SkRefCnt { */ uint32_t writeSize() const; + void interpolate(const SkPathRef& ending, SkScalar weight, SkPathRef* out) const; + /** * Gets an ID that uniquely identifies the contents of the path ref. If two path refs have the * same ID then they have the same verbs and points. However, two path refs may have the same @@ -257,11 +304,23 @@ class SK_API SkPathRef : public ::SkRefCnt { */ uint32_t genID() const; + struct GenIDChangeListener { + virtual ~GenIDChangeListener() {} + virtual void onChange() = 0; + }; + + void addGenIDChangeListener(GenIDChangeListener* listener); + + SkDEBUGCODE(void validate() const;) + private: enum SerializationOffsets { - kIsFinite_SerializationShift = 25, // requires 1 bit - kIsOval_SerializationShift = 24, // requires 1 bit - kSegmentMask_SerializationShift = 0 // requires 4 bits + kRRectOrOvalStartIdx_SerializationShift = 28, // requires 3 bits + kRRectOrOvalIsCCW_SerializationShift = 27, // requires 1 bit + kIsRRect_SerializationShift = 26, // requires 1 bit + kIsFinite_SerializationShift = 25, // requires 1 bit + kIsOval_SerializationShift = 24, // requires 1 bit + kSegmentMask_SerializationShift = 0 // requires 4 bits }; SkPathRef() { @@ -274,6 +333,10 @@ class SK_API SkPathRef : public ::SkRefCnt { fGenerationID = kEmptyGenID; fSegmentMask = 0; fIsOval = false; + fIsRRect = false; + // The next two values don't matter unless fIsOval or fIsRRect are true. + fRRectOrOvalIsCCW = false; + fRRectOrOvalStartIdx = 0xAC; SkDEBUGCODE(fEditorsAttached = 0;) SkDEBUGCODE(this->validate();) } @@ -282,18 +345,14 @@ class SK_API SkPathRef : public ::SkRefCnt { // Return true if the computed bounds are finite. static bool ComputePtBounds(SkRect* bounds, const SkPathRef& ref) { - int count = ref.countPoints(); - if (count <= 1) { // we ignore just 1 point (moveto) - bounds->setEmpty(); - return count ? ref.points()->isFinite() : true; - } else { - return bounds->setBoundsCheck(ref.points(), count); - } + return bounds->setBoundsCheck(ref.points(), ref.countPoints()); } // called, if dirty, by getBounds() void computeBounds() const { SkDEBUGCODE(this->validate();) + // TODO(mtklein): remove fBoundsIsDirty and fIsFinite, + // using an inverted rect instead of fBoundsIsDirty and always recalculating fIsFinite. SkASSERT(fBoundsIsDirty); fIsFinite = ComputePtBounds(&fBounds, *this); @@ -325,6 +384,7 @@ class SK_API SkPathRef : public ::SkRefCnt { fSegmentMask = 0; fIsOval = false; + fIsRRect = false; size_t newSize = sizeof(uint8_t) * verbCount + sizeof(SkPoint) * pointCount; size_t newReserve = sizeof(uint8_t) * reserveVerbs + sizeof(SkPoint) * reservePoints; @@ -417,30 +477,43 @@ class SK_API SkPathRef : public ::SkRefCnt { return reinterpret_cast(fVerbs) - reinterpret_cast(fPoints); } - SkDEBUGCODE(void validate() const;) - /** * Called the first time someone calls CreateEmpty to actually create the singleton. */ - static void CreateEmptyImpl(SkPathRef** empty); + friend SkPathRef* sk_create_empty_pathref(); - void setIsOval(bool isOval) { fIsOval = isOval; } + void setIsOval(bool isOval, bool isCCW, unsigned start) { + fIsOval = isOval; + fRRectOrOvalIsCCW = isCCW; + fRRectOrOvalStartIdx = start; + } + + void setIsRRect(bool isRRect, bool isCCW, unsigned start) { + fIsRRect = isRRect; + fRRectOrOvalIsCCW = isCCW; + fRRectOrOvalStartIdx = start; + } + // called only by the editor. Note that this is not a const function. SkPoint* getPoints() { SkDEBUGCODE(this->validate();) fIsOval = false; + fIsRRect = false; return fPoints; } + const SkPoint* getPoints() const { + SkDEBUGCODE(this->validate();) + return fPoints; + } + + void callGenIDChangeListeners(); + enum { kMinSize = 256, }; - mutable SkRect fBounds; - uint8_t fSegmentMask; - mutable uint8_t fBoundsIsDirty; - mutable SkBool8 fIsFinite; // only meaningful if bounds are valid - mutable SkBool8 fIsOval; + mutable SkRect fBounds; SkPoint* fPoints; // points to begining of the allocation uint8_t* fVerbs; // points just past the end of the allocation (verbs grow backwards) @@ -455,8 +528,21 @@ class SK_API SkPathRef : public ::SkRefCnt { mutable uint32_t fGenerationID; SkDEBUGCODE(int32_t fEditorsAttached;) // assert that only one editor in use at any time. + SkTDArray fGenIDChangeListeners; // pointers are owned + + mutable uint8_t fBoundsIsDirty; + mutable SkBool8 fIsFinite; // only meaningful if bounds are valid + + SkBool8 fIsOval; + SkBool8 fIsRRect; + // Both the circle and rrect special cases have a notion of direction and starting point + // The next two variables store that information for either. + SkBool8 fRRectOrOvalIsCCW; + uint8_t fRRectOrOvalStartIdx; + uint8_t fSegmentMask; + friend class PathRefTest_Private; - typedef SkRefCnt INHERITED; + friend class ForceIsRRect_Private; // unit test isRRect }; #endif diff --git a/libskia/include/core/SkPicture.h b/libskia/include/core/SkPicture.h index a1d7644e..8047858b 100644 --- a/libskia/include/core/SkPicture.h +++ b/libskia/include/core/SkPicture.h @@ -1,4 +1,3 @@ - /* * Copyright 2007 The Android Open Source Project * @@ -6,43 +5,39 @@ * found in the LICENSE file. */ - #ifndef SkPicture_DEFINED #define SkPicture_DEFINED -#include "SkBitmap.h" -#include "SkImageDecoder.h" #include "SkRefCnt.h" +#include "SkRect.h" +#include "SkTypes.h" -class SkBBoxHierarchy; +class GrContext; +class SkBigPicture; +class SkBitmap; class SkCanvas; -class SkDrawPictureCallback; class SkData; -class SkPicturePlayback; -class SkPictureRecord; +class SkImage; +class SkImageDeserializer; +class SkPath; +class SkPictureData; +class SkPixelSerializer; +class SkReadBuffer; +class SkRefCntSet; class SkStream; +class SkTypefacePlayback; class SkWStream; - +class SkWriteBuffer; struct SkPictInfo; /** \class SkPicture - The SkPicture class records the drawing commands made to a canvas, to - be played back at a later time. + An SkPicture records drawing commands made to a canvas to be played back at a later time. + This base class handles serialization and a few other miscellany. */ class SK_API SkPicture : public SkRefCnt { public: - SK_DECLARE_INST_COUNT(SkPicture) - - /** The constructor prepares the picture to record. - @param width the width of the virtual device the picture records. - @param height the height of the virtual device the picture records. - */ - SkPicture(); - /** Make a copy of the contents of src. If src records more drawing after - this call, those elements will not appear in this picture. - */ - SkPicture(const SkPicture& src); + virtual ~SkPicture(); /** * Function signature defining a function that sets up an SkBitmap from encoded data. On @@ -59,216 +54,180 @@ class SK_API SkPicture : public SkRefCnt { /** * Recreate a picture that was serialized into a stream. - * @param SkStream Serialized picture data. - * @param proc Function pointer for installing pixelrefs on SkBitmaps representing the - * encoded bitmap data from the stream. - * @return A new SkPicture representing the serialized data, or NULL if the stream is - * invalid. + * + * Any serialized images in the stream will be passed the image-deserializer, or if that is + * null, to the default deserializer that will call SkImage::MakeFromEncoded(). */ - static SkPicture* CreateFromStream(SkStream*, - InstallPixelRefProc proc = &SkImageDecoder::DecodeMemory); - - virtual ~SkPicture(); + static sk_sp MakeFromStream(SkStream*, SkImageDeserializer*); + static sk_sp MakeFromStream(SkStream*); + static sk_sp MakeFromData(const void* data, size_t size, + SkImageDeserializer* = nullptr); + static sk_sp MakeFromData(const SkData* data, SkImageDeserializer* = nullptr); /** - * Swap the contents of the two pictures. Guaranteed to succeed. - */ - void swap(SkPicture& other); - - /** - * Creates a thread-safe clone of the picture that is ready for playback. + * Recreate a picture that was serialized into a buffer. If the creation requires bitmap + * decoding, the decoder must be set on the SkReadBuffer parameter by calling + * SkReadBuffer::setBitmapDecoder() before calling SkPicture::CreateFromBuffer(). + * @param SkReadBuffer Serialized picture data. + * @return A new SkPicture representing the serialized data, or NULL if the buffer is + * invalid. */ - SkPicture* clone() const; + static sk_sp MakeFromBuffer(SkReadBuffer&); /** - * Creates multiple thread-safe clones of this picture that are ready for - * playback. The resulting clones are stored in the provided array of - * SkPictures. - */ - void clone(SkPicture* pictures, int count) const; - - enum RecordingFlags { - /* This flag specifies that when clipPath() is called, the path will - be faithfully recorded, but the recording canvas' current clip will - only see the path's bounds. This speeds up the recording process - without compromising the fidelity of the playback. The only side- - effect for recording is that calling getTotalClip() or related - clip-query calls will reflect the path's bounds, not the actual - path. - */ - kUsePathBoundsForClip_RecordingFlag = 0x01, - /* This flag causes the picture to compute bounding boxes and build - up a spatial hierarchy (currently an R-Tree), plus a tree of Canvas' - usually stack-based clip/etc state. This requires an increase in - recording time (often ~2x; likely more for very complex pictures), - but allows us to perform much faster culling at playback time, and - completely avoid some unnecessary clips and other operations. This - is ideal for tiled rendering, or any other situation where you're - drawing a fraction of a large scene into a smaller viewport. - - In most cases the record cost is offset by the playback improvement - after a frame or two of tiled rendering (and complex pictures that - induce the worst record times will generally get the largest - speedups at playback time). - - Note: Currently this is not serializable, the bounding data will be - discarded if you serialize into a stream and then deserialize. - */ - kOptimizeForClippedPlayback_RecordingFlag = 0x02, - /* - This flag disables all the picture recording optimizations (i.e., - those in SkPictureRecord). It is mainly intended for testing the - existing optimizations (i.e., to actually have the pattern - appear in an .skp we have to disable the optimization). This - option doesn't affect the optimizations controlled by - 'kOptimizeForClippedPlayback_RecordingFlag'. - */ - kDisableRecordOptimizations_RecordingFlag = 0x04 - }; - - /** Returns the canvas that records the drawing commands. - @param width the base width for the picture, as if the recording - canvas' bitmap had this width. - @param height the base width for the picture, as if the recording - canvas' bitmap had this height. - @param recordFlags optional flags that control recording. - @return the picture canvas. - */ - SkCanvas* beginRecording(int width, int height, uint32_t recordFlags = 0); - - /** Returns the recording canvas if one is active, or NULL if recording is - not active. This does not alter the refcnt on the canvas (if present). - */ - SkCanvas* getRecordingCanvas() const; - /** Signal that the caller is done recording. This invalidates the canvas - returned by beginRecording/getRecordingCanvas, and prepares the picture - for drawing. Note: this happens implicitly the first time the picture - is drawn. + * Subclasses of this can be passed to playback(). During the playback + * of the picture, this callback will periodically be invoked. If its + * abort() returns true, then picture playback will be interrupted. + * + * The resulting drawing is undefined, as there is no guarantee how often the + * callback will be invoked. If the abort happens inside some level of nested + * calls to save(), restore will automatically be called to return the state + * to the same level it was before the playback call was made. */ - void endRecording(); + class SK_API AbortCallback { + public: + AbortCallback() {} + virtual ~AbortCallback() {} + virtual bool abort() = 0; + }; - /** Replays the drawing commands on the specified canvas. This internally - calls endRecording() if that has not already been called. + /** Replays the drawing commands on the specified canvas. Note that + this has the effect of unfurling this picture into the destination + canvas. Using the SkCanvas::drawPicture entry point gives the destination + canvas the option of just taking a ref. @param canvas the canvas receiving the drawing commands. + @param callback a callback that allows interruption of playback */ - void draw(SkCanvas* canvas, SkDrawPictureCallback* = NULL); + virtual void playback(SkCanvas*, AbortCallback* = NULL) const = 0; - /** Return the width of the picture's recording canvas. This - value reflects what was passed to setSize(), and does not necessarily - reflect the bounds of what has been recorded into the picture. - @return the width of the picture's recording canvas - */ - int width() const { return fWidth; } + /** Return a cull rect for this picture. + Ops recorded into this picture that attempt to draw outside the cull might not be drawn. + */ + virtual SkRect cullRect() const = 0; - /** Return the height of the picture's recording canvas. This - value reflects what was passed to setSize(), and does not necessarily - reflect the bounds of what has been recorded into the picture. - @return the height of the picture's recording canvas - */ - int height() const { return fHeight; } + /** Returns a non-zero value unique among all pictures. */ + uint32_t uniqueID() const; /** - * Function to encode an SkBitmap to an SkData. A function with this - * signature can be passed to serialize() and SkOrderedWriteBuffer. - * Returning NULL will tell the SkOrderedWriteBuffer to use - * SkBitmap::flatten() to store the bitmap. - * @param pixelRefOffset Output parameter, telling the deserializer what - * offset in the bm's pixelRef corresponds to the encoded data. - * @return SkData If non-NULL, holds encoded data representing the passed - * in bitmap. The caller is responsible for calling unref(). + * Serialize the picture to SkData. If non nullptr, pixel-serializer will be used to + * customize how images reference by the picture are serialized/compressed. */ - typedef SkData* (*EncodeBitmap)(size_t* pixelRefOffset, const SkBitmap& bm); + sk_sp serialize(SkPixelSerializer* = nullptr) const; /** - * Serialize to a stream. If non NULL, encoder will be used to encode - * any bitmaps in the picture. - * encoder will never be called with a NULL pixelRefOffset. + * Serialize to a stream. If non nullptr, pixel-serializer will be used to + * customize how images reference by the picture are serialized/compressed. */ - void serialize(SkWStream*, EncodeBitmap encoder = NULL) const; + void serialize(SkWStream*, SkPixelSerializer* = nullptr) const; + + /** + * Serialize to a buffer. + */ + void flatten(SkWriteBuffer&) const; /** * Returns true if any bitmaps may be produced when this SkPicture * is replayed. - * Returns false if called while still recording. */ - bool willPlayBackBitmaps() const; + virtual bool willPlayBackBitmaps() const = 0; -#ifdef SK_BUILD_FOR_ANDROID - /** Signals that the caller is prematurely done replaying the drawing - commands. This can be called from a canvas virtual while the picture - is drawing. Has no effect if the picture is not drawing. - @deprecated preserving for legacy purposes + /** Return the approximate number of operations in this picture. This + * number may be greater or less than the number of SkCanvas calls + * recorded: some calls may be recorded as more than one operation, or some + * calls may be optimized away. + */ + virtual int approximateOpCount() const = 0; + + /** Returns the approximate byte size of this picture, not including large ref'd objects. */ + virtual size_t approximateBytesUsed() const = 0; + + /** Return true if the SkStream/Buffer represents a serialized picture, and + fills out SkPictInfo. After this function returns, the data source is not + rewound so it will have to be manually reset before passing to + CreateFromStream or CreateFromBuffer. Note, CreateFromStream and + CreateFromBuffer perform this check internally so these entry points are + intended for stand alone tools. + If false is returned, SkPictInfo is unmodified. */ - void abortPlayback(); -#endif + static bool InternalOnly_StreamIsSKP(SkStream*, SkPictInfo*); + static bool InternalOnly_BufferIsSKP(SkReadBuffer*, SkPictInfo*); -protected: - // V2 : adds SkPixelRef's generation ID. - // V3 : PictInfo tag at beginning, and EOF tag at the end - // V4 : move SkPictInfo to be the header - // V5 : don't read/write FunctionPtr on cross-process (we can detect that) - // V6 : added serialization of SkPath's bounds (and packed its flags tighter) - // V7 : changed drawBitmapRect(IRect) to drawBitmapRectToRect(Rect) - // V8 : Add an option for encoding bitmaps - // V9 : Allow the reader and writer of an SKP disagree on whether to support - // SK_SUPPORT_HINTING_SCALE_FACTOR - // V10: add drawRRect, drawOval, clipRRect - // V11: modify how readBitmap and writeBitmap store their info. - // V12: add conics to SkPath, use new SkPathRef flattening - // V13: add flag to drawBitmapRectToRect - // parameterize blurs by sigma rather than radius - // V14: Add flags word to PathRef serialization - // V15: Remove A1 bitmpa config (and renumber remaining configs) - // V16: Move SkPath's isOval flag to SkPathRef - // V17: SkPixelRef now writes SkImageInfo -#ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V16_AND_ALL_OTHER_INSTANCES_TOO - static const uint32_t PRIOR_PICTURE_VERSION = 15; // TODO: remove when .skps regenerated +#ifdef SK_SUPPORT_LEGACY_PICTURE_GPUVETO + /** Return true if the picture is suitable for rendering on the GPU. */ + bool suitableForGpuRasterization(GrContext*, const char** whyNot = NULL) const; #endif - static const uint32_t PICTURE_VERSION = 17; - - // fPlayback, fRecord, fWidth & fHeight are protected to allow derived classes to - // install their own SkPicturePlayback-derived players,SkPictureRecord-derived - // recorders and set the picture size - SkPicturePlayback* fPlayback; - SkPictureRecord* fRecord; - int fWidth, fHeight; - - // Create a new SkPicture from an existing SkPicturePlayback. Ref count of - // playback is unchanged. - SkPicture(SkPicturePlayback*, int width, int height); - - // For testing. Derived classes may instantiate an alternate - // SkBBoxHierarchy implementation - virtual SkBBoxHierarchy* createBBoxHierarchy() const; - - // Return true if the SkStream represents a serialized picture, and fills out - // SkPictInfo. After this function returns, the SkStream is not rewound; it - // will be ready to be parsed to create an SkPicturePlayback. - // If false is returned, SkPictInfo is unmodified. - static bool StreamIsSKP(SkStream*, SkPictInfo*); -private: - friend class SkFlatPicture; - friend class SkPicturePlayback; - typedef SkRefCnt INHERITED; -}; + // Sent via SkMessageBus from destructor. + struct DeletionMessage { int32_t fUniqueID; }; // TODO: -> uint32_t? -/** - * Subclasses of this can be passed to canvas.drawPicture. During the drawing - * of the picture, this callback will periodically be invoked. If its - * abortDrawing() returns true, then picture playback will be interrupted. - * - * The resulting drawing is undefined, as there is no guarantee how often the - * callback will be invoked. If the abort happens inside some level of nested - * calls to save(), restore will automatically be called to return the state - * to the same level it was before the drawPicture call was made. - */ -class SK_API SkDrawPictureCallback { -public: - SkDrawPictureCallback() {} - virtual ~SkDrawPictureCallback() {} + // Returns NULL if this is not an SkBigPicture. + virtual const SkBigPicture* asSkBigPicture() const { return NULL; } + + // Global setting to enable or disable security precautions for serialization. + static void SetPictureIOSecurityPrecautionsEnabled_Dangerous(bool set); + static bool PictureIOSecurityPrecautionsEnabled(); - virtual bool abortDrawing() = 0; +private: + // Subclass whitelist. + SkPicture(); + friend class SkBigPicture; + friend class SkEmptyPicture; + template friend class SkMiniPicture; + + void serialize(SkWStream*, SkPixelSerializer*, SkRefCntSet* typefaces) const; + static sk_sp MakeFromStream(SkStream*, SkImageDeserializer*, SkTypefacePlayback*); + friend class SkPictureData; + + virtual int numSlowPaths() const = 0; + friend class SkPictureGpuAnalyzer; + friend struct SkPathCounter; + + // V35: Store SkRect (rather then width & height) in header + // V36: Remove (obsolete) alphatype from SkColorTable + // V37: Added shadow only option to SkDropShadowImageFilter (last version to record CLEAR) + // V38: Added PictureResolution option to SkPictureImageFilter + // V39: Added FilterLevel option to SkPictureImageFilter + // V40: Remove UniqueID serialization from SkImageFilter. + // V41: Added serialization of SkBitmapSource's filterQuality parameter + // V42: Added a bool to SkPictureShader serialization to indicate did-we-serialize-a-picture? + // V43: Added DRAW_IMAGE and DRAW_IMAGE_RECT opt codes to serialized data + // V44: Move annotations from paint to drawAnnotation + // V45: Add invNormRotation to SkLightingShader. + // V46: Add drawTextRSXform + // V47: Add occluder rect to SkBlurMaskFilter + // V48: Read and write extended SkTextBlobs. + // V49: Gradients serialized as SkColor4f + SkColorSpace + // V50: SkXfermode -> SkBlendMode + // V51: more SkXfermode -> SkBlendMode + + // Only SKPs within the min/current picture version range (inclusive) can be read. + static const uint32_t MIN_PICTURE_VERSION = 35; // Produced by Chrome M39. + static const uint32_t CURRENT_PICTURE_VERSION = 51; + + static_assert(MIN_PICTURE_VERSION <= 41, + "Remove kFontFileName and related code from SkFontDescriptor.cpp."); + + static_assert(MIN_PICTURE_VERSION <= 42, + "Remove COMMENT API handlers from SkPicturePlayback.cpp"); + + static_assert(MIN_PICTURE_VERSION <= 43, + "Remove SkBitmapSourceDeserializer."); + + static_assert(MIN_PICTURE_VERSION <= 45, + "Remove decoding of old SkTypeface::Style from SkFontDescriptor.cpp."); + + static_assert(MIN_PICTURE_VERSION <= 48, + "Remove legacy gradient deserialization code from SkGradientShader.cpp."); + + static bool IsValidPictInfo(const SkPictInfo& info); + static sk_sp Forwardport(const SkPictInfo&, + const SkPictureData*, + SkReadBuffer* buffer); + + SkPictInfo createHeader() const; + SkPictureData* backport() const; + + mutable uint32_t fUniqueID; }; #endif diff --git a/libskia/include/core/SkPictureAnalyzer.h b/libskia/include/core/SkPictureAnalyzer.h new file mode 100644 index 00000000..62dac30f --- /dev/null +++ b/libskia/include/core/SkPictureAnalyzer.h @@ -0,0 +1,66 @@ +/* + * Copyright 2016 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkPictureAnalyzer_DEFINED +#define SkPictureAnalyzer_DEFINED + +#include "SkCanvas.h" +#include "SkRefCnt.h" +#include "SkRegion.h" +#include "SkTypes.h" + +#if SK_SUPPORT_GPU +#include "GrContext.h" + +class SkPath; +class SkPicture; + +/** \class SkPictureGpuAnalyzer + + Gathers GPU-related statistics for one or more SkPictures. +*/ +class SK_API SkPictureGpuAnalyzer final : public SkNoncopyable { +public: + explicit SkPictureGpuAnalyzer(sk_sp = nullptr); + explicit SkPictureGpuAnalyzer(const sk_sp& picture, + sk_sp = nullptr); + + /** + * Process the given picture and accumulate its stats. + */ + void analyzePicture(const SkPicture*); + + /** + * Process an explicit clipPath op. + */ + void analyzeClipPath(const SkPath&, SkCanvas::ClipOp, bool doAntiAlias); + + /** + * Reset all accumulated stats. + */ + void reset(); + + /** + * Returns true if the analyzed pictures are suitable for rendering on the GPU. + */ + bool suitableForGpuRasterization(const char** whyNot = nullptr) const; + + /** + * Returns the number of commands which are slow to draw on the GPU, capped at the predicate + * max. + */ + uint32_t numSlowGpuCommands() { return fNumSlowPaths; } + +private: + uint32_t fNumSlowPaths; + + typedef SkNoncopyable INHERITED; +}; + +#endif // SK_SUPPORT_GPU + +#endif // SkPictureAnalyzer_DEFINED diff --git a/libskia/include/core/SkPictureRecorder.h b/libskia/include/core/SkPictureRecorder.h new file mode 100644 index 00000000..7bf081d0 --- /dev/null +++ b/libskia/include/core/SkPictureRecorder.h @@ -0,0 +1,129 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkPictureRecorder_DEFINED +#define SkPictureRecorder_DEFINED + +#include "../private/SkMiniRecorder.h" +#include "SkBBHFactory.h" +#include "SkPicture.h" +#include "SkRefCnt.h" + +#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK +namespace android { + class Picture; +}; +#endif + +class GrContext; +class SkCanvas; +class SkDrawable; +class SkPictureRecord; +class SkRecord; +class SkRecorder; + +class SK_API SkPictureRecorder : SkNoncopyable { +public: + SkPictureRecorder(); + ~SkPictureRecorder(); + + enum RecordFlags { + // If you call drawPicture() or drawDrawable() on the recording canvas, this flag forces + // that object to playback its contents immediately rather than reffing the object. + kPlaybackDrawPicture_RecordFlag = 1 << 0, + }; + + enum FinishFlags { + kReturnNullForEmpty_FinishFlag = 1 << 0, // no draw-ops will return nullptr + }; + + /** Returns the canvas that records the drawing commands. + @param bounds the cull rect used when recording this picture. Any drawing the falls outside + of this rect is undefined, and may be drawn or it may not. + @param bbhFactory factory to create desired acceleration structure + @param recordFlags optional flags that control recording. + @return the canvas. + */ + SkCanvas* beginRecording(const SkRect& bounds, + SkBBHFactory* bbhFactory = NULL, + uint32_t recordFlags = 0); + + SkCanvas* beginRecording(SkScalar width, SkScalar height, + SkBBHFactory* bbhFactory = NULL, + uint32_t recordFlags = 0) { + return this->beginRecording(SkRect::MakeWH(width, height), bbhFactory, recordFlags); + } + + /** Returns the recording canvas if one is active, or NULL if recording is + not active. This does not alter the refcnt on the canvas (if present). + */ + SkCanvas* getRecordingCanvas(); + + /** + * Signal that the caller is done recording. This invalidates the canvas returned by + * beginRecording/getRecordingCanvas. Ownership of the object is passed to the caller, who + * must call unref() when they are done using it. + * + * The returned picture is immutable. If during recording drawables were added to the canvas, + * these will have been "drawn" into a recording canvas, so that this resulting picture will + * reflect their current state, but will not contain a live reference to the drawables + * themselves. + */ + sk_sp finishRecordingAsPicture(uint32_t endFlags = 0); + + /** + * Signal that the caller is done recording, and update the cull rect to use for bounding + * box hierarchy (BBH) generation. The behavior is the same as calling + * endRecordingAsPicture(), except that this method updates the cull rect initially passed + * into beginRecording. + * @param cullRect the new culling rectangle to use as the overall bound for BBH generation + * and subsequent culling operations. + * @return the picture containing the recorded content. + */ + sk_sp finishRecordingAsPictureWithCull(const SkRect& cullRect, + uint32_t endFlags = 0); + + /** + * Signal that the caller is done recording. This invalidates the canvas returned by + * beginRecording/getRecordingCanvas. Ownership of the object is passed to the caller, who + * must call unref() when they are done using it. + * + * Unlike endRecordingAsPicture(), which returns an immutable picture, the returned drawable + * may contain live references to other drawables (if they were added to the recording canvas) + * and therefore this drawable will reflect the current state of those nested drawables anytime + * it is drawn or a new picture is snapped from it (by calling drawable->newPictureSnapshot()). + */ + sk_sp finishRecordingAsDrawable(uint32_t endFlags = 0); + +private: + void reset(); + + /** Replay the current (partially recorded) operation stream into + canvas. This call doesn't close the current recording. + */ +#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK + friend class android::Picture; +#endif + friend class SkPictureRecorderReplayTester; // for unit testing + void partialReplay(SkCanvas* canvas) const; + + bool fActivelyRecording; + uint32_t fFlags; + SkRect fCullRect; + sk_sp fBBH; +#ifdef SK_SUPPORT_LEGACY_CANVAS_IS_REFCNT + sk_sp fRecorder; +#else + std::unique_ptr fRecorder; +#endif + sk_sp fRecord; + SkMiniRecorder fMiniRecorder; + + typedef SkNoncopyable INHERITED; +}; + +#endif diff --git a/libskia/include/core/SkPixelRef.h b/libskia/include/core/SkPixelRef.h index 48114357..12a72f4e 100644 --- a/libskia/include/core/SkPixelRef.h +++ b/libskia/include/core/SkPixelRef.h @@ -1,4 +1,3 @@ - /* * Copyright 2008 The Android Open Source Project * @@ -6,39 +5,26 @@ * found in the LICENSE file. */ - #ifndef SkPixelRef_DEFINED #define SkPixelRef_DEFINED +#include "../private/SkAtomics.h" +#include "../private/SkMutex.h" +#include "../private/SkTDArray.h" #include "SkBitmap.h" +#include "SkFilterQuality.h" +#include "SkImageInfo.h" +#include "SkPixmap.h" #include "SkRefCnt.h" +#include "SkSize.h" #include "SkString.h" -#include "SkFlattenable.h" -#include "SkImageInfo.h" -#include "SkTDArray.h" - -//#define SK_SUPPORT_LEGACY_ONLOCKPIXELS - -#ifdef SK_DEBUG - /** - * Defining SK_IGNORE_PIXELREF_SETPRELOCKED will force all pixelref - * subclasses to correctly handle lock/unlock pixels. For performance - * reasons, simple malloc-based subclasses call setPreLocked() to skip - * the overhead of implementing these calls. - * - * This build-flag disables that optimization, to add in debugging our - * call-sites, to ensure that they correctly balance their calls of - * lock and unlock. - */ -// #define SK_IGNORE_PIXELREF_SETPRELOCKED -#endif +#include "SkYUVSizeInfo.h" class SkColorTable; -class SkData; struct SkIRect; -class SkMutex; class GrTexture; +class SkDiscardableMemory; /** \class SkPixelRef @@ -48,12 +34,9 @@ class GrTexture; This class can be shared/accessed between multiple threads. */ -class SK_API SkPixelRef : public SkFlattenable { +class SK_API SkPixelRef : public SkRefCnt { public: - SK_DECLARE_INST_COUNT(SkPixelRef) - explicit SkPixelRef(const SkImageInfo&); - SkPixelRef(const SkImageInfo&, SkBaseMutex* mutex); virtual ~SkPixelRef(); const SkImageInfo& info() const { @@ -69,11 +52,15 @@ class SK_API SkPixelRef : public SkFlattenable { */ SkColorTable* colorTable() const { return fRec.fColorTable; } + size_t rowBytes() const { return fRec.fRowBytes; } + /** * To access the actual pixels of a pixelref, it must be "locked". * Calling lockPixels returns a LockRec struct (on success). */ struct LockRec { + LockRec() : fPixels(NULL), fColorTable(NULL) {} + void* fPixels; SkColorTable* fColorTable; size_t fRowBytes; @@ -85,11 +72,7 @@ class SK_API SkPixelRef : public SkFlattenable { } }; - /** - * Returns true if the lockcount > 0 - */ - bool isLocked() const { return fLockCount > 0; } - + SkDEBUGCODE(bool isLocked() const { return fLockCount > 0; }) SkDEBUGCODE(int getLockCount() const { return fLockCount; }) /** @@ -126,16 +109,36 @@ class SK_API SkPixelRef : public SkFlattenable { */ uint32_t getGenerationID() const; - /** Call this if you have changed the contents of the pixels. This will in- - turn cause a different generation ID value to be returned from - getGenerationID(). - */ +#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK + /** Returns a non-zero, unique value corresponding to this SkPixelRef. + Unlike the generation ID, this ID remains the same even when the pixels + are changed. IDs are not reused (until uint32_t wraps), so it is safe + to consider this ID unique even after this SkPixelRef is deleted. + + Can be used as a key which uniquely identifies this SkPixelRef + regardless of changes to its pixels or deletion of this object. + */ + uint32_t getStableID() const { return fStableID; } +#endif + + /** + * Call this if you have changed the contents of the pixels. This will in- + * turn cause a different generation ID value to be returned from + * getGenerationID(). + */ void notifyPixelsChanged(); + /** + * Change the info's AlphaType. Note that this does not automatically + * invalidate the generation ID. If the pixel values themselves have + * changed, then you must explicitly call notifyPixelsChanged() as well. + */ + void changeAlphaType(SkAlphaType at); + /** Returns true if this pixelref is marked as immutable, meaning that the contents of its pixels will not change for the lifetime of the pixelref. */ - bool isImmutable() const { return fIsImmutable; } + bool isImmutable() const { return fMutability != kMutable; } /** Marks this pixelref is immutable, meaning that the contents of its pixels will not change for the lifetime of the pixelref. This state can @@ -164,85 +167,59 @@ class SK_API SkPixelRef : public SkFlattenable { */ void setURI(const SkString& uri) { fURI = uri; } - /** - * If the pixelRef has an encoded (i.e. compressed) representation, - * return a ref to its data. If the pixelRef - * is uncompressed or otherwise does not have this form, return NULL. - * - * If non-null is returned, the caller is responsible for calling unref() - * on the data when it is finished. - */ - SkData* refEncodedData() { - return this->onRefEncodedData(); - } + struct LockRequest { + SkISize fSize; + SkFilterQuality fQuality; + }; - /** - * Experimental -- tells the caller if it is worth it to call decodeInto(). - * Just an optimization at this point, to avoid checking the cache first. - * We may remove/change this call in the future. - */ - bool implementsDecodeInto() { - return this->onImplementsDecodeInto(); - } + struct LockResult { + LockResult() : fPixels(NULL), fCTable(NULL) {} - /** - * Return a decoded instance of this pixelRef in bitmap. If this cannot be - * done, return false and the bitmap parameter is ignored/unchanged. - * - * pow2 is the requeste power-of-two downscale that the caller needs. This - * can be ignored, and the "original" size can be returned, but if the - * underlying codec can efficiently return a smaller size, that should be - * done. Some examples: - * - * To request the "base" version (original scale), pass 0 for pow2 - * To request 1/2 scale version (1/2 width, 1/2 height), pass 1 for pow2 - * To request 1/4 scale version (1/4 width, 1/4 height), pass 2 for pow2 - * ... - * - * If this returns true, then bitmap must be "locked" such that - * bitmap->getPixels() will return the correct address. - */ - bool decodeInto(int pow2, SkBitmap* bitmap) { - SkASSERT(pow2 >= 0); - return this->onDecodeInto(pow2, bitmap); - } + void (*fUnlockProc)(void* ctx); + void* fUnlockContext; - /** Are we really wrapping a texture instead of a bitmap? - */ - virtual GrTexture* getTexture() { return NULL; } + const void* fPixels; + SkColorTable* fCTable; // should be NULL unless colortype is kIndex8 + size_t fRowBytes; + SkISize fSize; - bool readPixels(SkBitmap* dst, const SkIRect* subset = NULL); + void unlock() { + if (fUnlockProc) { + fUnlockProc(fUnlockContext); + fUnlockProc = NULL; // can't unlock twice! + } + } + }; - /** - * Makes a deep copy of this PixelRef, respecting the requested config. - * @param config Desired config. - * @param subset Subset of this PixelRef to copy. Must be fully contained within the bounds of - * of this PixelRef. - * @return A new SkPixelRef, or NULL if either there is an error (e.g. the destination could - * not be created with the given config), or this PixelRef does not support deep - * copies. - */ - virtual SkPixelRef* deepCopy(SkBitmap::Config config, const SkIRect* subset = NULL) { - return NULL; - } + bool requestLock(const LockRequest&, LockResult*); -#ifdef SK_BUILD_FOR_ANDROID /** - * Acquire a "global" ref on this object. - * The default implementation just calls ref(), but subclasses can override - * this method to implement additional behavior. + * If this can efficiently return YUV data, this should return true. + * Otherwise this returns false and does not modify any of the parameters. + * + * @param sizeInfo Output parameter indicating the sizes and required + * allocation widths of the Y, U, and V planes. + * @param colorSpace Output parameter. */ - virtual void globalRef(void* data=NULL); + bool queryYUV8(SkYUVSizeInfo* sizeInfo, SkYUVColorSpace* colorSpace) const { + return this->onQueryYUV8(sizeInfo, colorSpace); + } /** - * Release a "global" ref on this object. - * The default implementation just calls unref(), but subclasses can override - * this method to implement additional behavior. + * Returns true on success and false on failure. + * Copies YUV data into the provided YUV planes. + * + * @param sizeInfo Needs to exactly match the values returned by the + * query, except the WidthBytes may be larger than the + * recommendation (but not smaller). + * @param planes Memory for each of the Y, U, and V planes. */ - virtual void globalUnref(); -#endif + bool getYUV8Planes(const SkYUVSizeInfo& sizeInfo, void* planes[3]) { + return this->onGetYUV8Planes(sizeInfo, planes); + } - SK_DEFINE_FLATTENABLE_TYPE(SkPixelRef) + /** Populates dst with the pixels of this pixelRef, converting them to colorType. */ + bool readPixels(SkBitmap* dst, SkColorType colorType, const SkIRect* subset = NULL); // Register a listener that may be called the next time our generation ID changes. // @@ -260,11 +237,20 @@ class SK_API SkPixelRef : public SkFlattenable { // Takes ownership of listener. void addGenIDChangeListener(GenIDChangeListener* listener); + // Call when this pixelref is part of the key to a resourcecache entry. This allows the cache + // to know automatically those entries can be purged when this pixelref is changed or deleted. + void notifyAddedToCache() { + fAddedToCache.store(true); + } + + virtual SkDiscardableMemory* diagnostic_only_getDiscardable() const { return NULL; } + + /** + * Returns true if the pixels are generated on-the-fly (when required). + */ + bool isLazyGenerated() const { return this->onIsLazyGenerated(); } + protected: -#ifdef SK_SUPPORT_LEGACY_ONLOCKPIXELS - virtual void* onLockPixels(SkColorTable**); - virtual bool onNewLockPixels(LockRec*); -#else /** * On success, returns true and fills out the LockRec for the pixels. On * failure returns false and ignores the LockRec parameter. @@ -273,7 +259,6 @@ class SK_API SkPixelRef : public SkFlattenable { * method need not do that. */ virtual bool onNewLockPixels(LockRec*) = 0; -#endif /** * Balancing the previous successful call to onNewLockPixels. The locked @@ -288,21 +273,23 @@ class SK_API SkPixelRef : public SkFlattenable { /** Default impl returns true */ virtual bool onLockPixelsAreWritable() const; - // returns false; - virtual bool onImplementsDecodeInto(); - // returns false; - virtual bool onDecodeInto(int pow2, SkBitmap* bitmap); - /** * For pixelrefs that don't have access to their raw pixels, they may be * able to make a copy of them (e.g. if the pixels are on the GPU). * * The base class implementation returns false; */ - virtual bool onReadPixels(SkBitmap* dst, const SkIRect* subsetOrNull); + virtual bool onReadPixels(SkBitmap* dst, SkColorType colorType, const SkIRect* subsetOrNull); - // default impl returns NULL. - virtual SkData* onRefEncodedData(); + // default impl does nothing. + virtual void onNotifyPixelsChanged(); + + virtual bool onQueryYUV8(SkYUVSizeInfo*, SkYUVColorSpace*) const { + return false; + } + virtual bool onGetYUV8Planes(const SkYUVSizeInfo&, void*[3] /*planes*/) { + return false; + } /** * Returns the size (in bytes) of the internally allocated memory. @@ -314,14 +301,14 @@ class SK_API SkPixelRef : public SkFlattenable { */ virtual size_t getAllocatedSizeInBytes() const; + virtual bool onRequestLock(const LockRequest&, LockResult*); + + virtual bool onIsLazyGenerated() const { return false; } + /** Return the mutex associated with this pixelref. This value is assigned in the constructor, and cannot change during the lifetime of the object. */ - SkBaseMutex* mutex() const { return fMutex; } - - // serialization - SkPixelRef(SkFlattenableReadBuffer&, SkBaseMutex*); - virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE; + SkBaseMutex* mutex() const { return &fMutex; } // only call from constructor. Flags this to always be locked, removing // the need to grab the mutex and call onLockPixels/onUnlockPixels. @@ -329,37 +316,74 @@ class SK_API SkPixelRef : public SkFlattenable { void setPreLocked(void*, size_t rowBytes, SkColorTable*); private: - SkBaseMutex* fMutex; // must remain in scope for the life of this object + mutable SkMutex fMutex; + // mostly const. fInfo.fAlpahType can be changed at runtime. const SkImageInfo fInfo; // LockRec is only valid if we're in a locked state (isLocked()) LockRec fRec; int fLockCount; - mutable uint32_t fGenerationID; - mutable bool fUniqueGenerationID; + bool lockPixelsInsideMutex(); + + // Bottom bit indicates the Gen ID is unique. + bool genIDIsUnique() const { return SkToBool(fTaggedGenID.load() & 1); } + mutable SkAtomic fTaggedGenID; + +#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK + const uint32_t fStableID; +#endif SkTDArray fGenIDChangeListeners; // pointers are owned SkString fURI; - // can go from false to true, but never from true to false - bool fIsImmutable; + // Set true by caches when they cache content that's derived from the current pixels. + SkAtomic fAddedToCache; + + enum { + kMutable, // PixelRefs begin mutable. + kTemporarilyImmutable, // Considered immutable, but can revert to mutable. + kImmutable, // Once set to this state, it never leaves. + } fMutability : 8; // easily fits inside a byte + // only ever set in constructor, const after that - bool fPreLocked; + bool fPreLocked; void needsNewGenID(); void callGenIDChangeListeners(); - void setMutex(SkBaseMutex* mutex); + void setTemporarilyImmutable(); + void restoreMutability(); + friend class SkSurface_Raster; // For the two methods above. + + bool isPreLocked() const { return fPreLocked; } + friend class SkImage_Raster; + friend class SkSpecialImage_Raster; // When copying a bitmap to another with the same shape and config, we can safely // clone the pixelref generation ID too, which makes them equivalent under caching. friend class SkBitmap; // only for cloneGenID void cloneGenID(const SkPixelRef&); - typedef SkFlattenable INHERITED; + void setImmutableWithID(uint32_t genID); + friend class SkImage_Gpu; + friend class SkImageCacherator; + friend class SkSpecialImage_Gpu; + + typedef SkRefCnt INHERITED; +}; + +class SkPixelRefFactory : public SkRefCnt { +public: + /** + * Allocate a new pixelref matching the specified ImageInfo, allocating + * the memory for the pixels. If the ImageInfo requires a ColorTable, + * the pixelref will ref() the colortable. + * On failure return NULL. + */ + virtual SkPixelRef* create(const SkImageInfo&, size_t rowBytes, SkColorTable*) = 0; }; #endif diff --git a/libskia/include/core/SkPixelSerializer.h b/libskia/include/core/SkPixelSerializer.h new file mode 100644 index 00000000..b168f79d --- /dev/null +++ b/libskia/include/core/SkPixelSerializer.h @@ -0,0 +1,50 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkPixelSerializer_DEFINED +#define SkPixelSerializer_DEFINED + +#include "SkRefCnt.h" +#include "SkPixmap.h" + +class SkData; + +/** + * Interface for serializing pixels, e.g. SkBitmaps in an SkPicture. + */ +class SkPixelSerializer : public SkRefCnt { +public: + virtual ~SkPixelSerializer() {} + + /** + * Call to determine if the client wants to serialize the encoded data. If + * false, serialize another version (e.g. the result of encodePixels). + */ + bool useEncodedData(const void* data, size_t len) { + return this->onUseEncodedData(data, len); + } + + /** + * Call to get the client's version of encoding these pixels. If it + * returns NULL, serialize the raw pixels. + */ + SkData* encode(const SkPixmap& pixmap) { return this->onEncode(pixmap); } + +protected: + /** + * Return true if you want to serialize the encoded data, false if you want + * another version serialized (e.g. the result of this->encode()). + */ + virtual bool onUseEncodedData(const void* data, size_t len) = 0; + + /** + * If you want to encode these pixels, return the encoded data as an SkData + * Return null if you want to serialize the raw pixels. + */ + virtual SkData* onEncode(const SkPixmap&) = 0; +}; +#endif // SkPixelSerializer_DEFINED diff --git a/libskia/include/core/SkPixmap.h b/libskia/include/core/SkPixmap.h new file mode 100644 index 00000000..ce13297f --- /dev/null +++ b/libskia/include/core/SkPixmap.h @@ -0,0 +1,266 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkPixmap_DEFINED +#define SkPixmap_DEFINED + +#include "SkColor.h" +#include "SkFilterQuality.h" +#include "SkImageInfo.h" + +class SkColorTable; +class SkData; +struct SkMask; + +/** + * Pairs SkImageInfo with actual pixels and rowbytes. This class does not try to manage the + * lifetime of the pixel memory (nor the colortable if provided). + */ +class SK_API SkPixmap { +public: + SkPixmap() + : fPixels(NULL), fCTable(NULL), fRowBytes(0), fInfo(SkImageInfo::MakeUnknown(0, 0)) + {} + + SkPixmap(const SkImageInfo& info, const void* addr, size_t rowBytes, + SkColorTable* ctable = NULL) + : fPixels(addr), fCTable(ctable), fRowBytes(rowBytes), fInfo(info) + { + if (kIndex_8_SkColorType == info.colorType()) { + SkASSERT(ctable); + } else { + SkASSERT(NULL == ctable); + } + } + + void reset(); + void reset(const SkImageInfo& info, const void* addr, size_t rowBytes, + SkColorTable* ctable = NULL); + void reset(const SkImageInfo& info) { + this->reset(info, NULL, 0, NULL); + } + + // overrides the colorspace in the SkImageInfo of the pixmap + void setColorSpace(sk_sp); + + /** + * If supported, set this pixmap to point to the pixels in the specified mask and return true. + * On failure, return false and set this pixmap to empty. + */ + bool SK_WARN_UNUSED_RESULT reset(const SkMask&); + + /** + * Computes the intersection of area and this pixmap. If that intersection is non-empty, + * set subset to that intersection and return true. + * + * On failure, return false and ignore the subset parameter. + */ + bool SK_WARN_UNUSED_RESULT extractSubset(SkPixmap* subset, const SkIRect& area) const; + + const SkImageInfo& info() const { return fInfo; } + size_t rowBytes() const { return fRowBytes; } + const void* addr() const { return fPixels; } + SkColorTable* ctable() const { return fCTable; } + + int width() const { return fInfo.width(); } + int height() const { return fInfo.height(); } + SkColorType colorType() const { return fInfo.colorType(); } + SkAlphaType alphaType() const { return fInfo.alphaType(); } + SkColorSpace* colorSpace() const { return fInfo.colorSpace(); } + bool isOpaque() const { return fInfo.isOpaque(); } + + SkIRect bounds() const { return SkIRect::MakeWH(this->width(), this->height()); } + + /** + * Return the rowbytes expressed as a number of pixels (like width and height). + */ + int rowBytesAsPixels() const { return int(fRowBytes >> this->shiftPerPixel()); } + + /** + * Return the shift amount per pixel (i.e. 0 for 1-byte per pixel, 1 for 2-bytes per pixel + * colortypes, 2 for 4-bytes per pixel colortypes). Return 0 for kUnknown_SkColorType. + */ + int shiftPerPixel() const { return fInfo.shiftPerPixel(); } + + uint64_t getSize64() const { return sk_64_mul(fInfo.height(), fRowBytes); } + uint64_t getSafeSize64() const { return fInfo.getSafeSize64(fRowBytes); } + size_t getSafeSize() const { return fInfo.getSafeSize(fRowBytes); } + + /** + * Converts the pixel at the specified coordinate to an unpremultiplied + * SkColor. Note: this ignores any SkColorSpace information, and may return + * lower precision data than is actually in the pixel. Alpha only + * colortypes (e.g. kAlpha_8_SkColorType) return black with the appropriate + * alpha set. The value is undefined for kUnknown_SkColorType or if x or y + * are out of bounds, or if the pixtap does not have any pixels. + */ + SkColor getColor(int x, int y) const; + + const void* addr(int x, int y) const { + return (const char*)fPixels + fInfo.computeOffset(x, y, fRowBytes); + } + const uint8_t* addr8() const { + SkASSERT(1 == SkColorTypeBytesPerPixel(fInfo.colorType())); + return reinterpret_cast(fPixels); + } + const uint16_t* addr16() const { + SkASSERT(2 == SkColorTypeBytesPerPixel(fInfo.colorType())); + return reinterpret_cast(fPixels); + } + const uint32_t* addr32() const { + SkASSERT(4 == SkColorTypeBytesPerPixel(fInfo.colorType())); + return reinterpret_cast(fPixels); + } + const uint64_t* addr64() const { + SkASSERT(8 == SkColorTypeBytesPerPixel(fInfo.colorType())); + return reinterpret_cast(fPixels); + } + const uint16_t* addrF16() const { + SkASSERT(8 == SkColorTypeBytesPerPixel(fInfo.colorType())); + SkASSERT(kRGBA_F16_SkColorType == fInfo.colorType()); + return reinterpret_cast(fPixels); + } + + // Offset by the specified x,y coordinates + + const uint8_t* addr8(int x, int y) const { + SkASSERT((unsigned)x < (unsigned)fInfo.width()); + SkASSERT((unsigned)y < (unsigned)fInfo.height()); + return (const uint8_t*)((const char*)this->addr8() + y * fRowBytes + (x << 0)); + } + const uint16_t* addr16(int x, int y) const { + SkASSERT((unsigned)x < (unsigned)fInfo.width()); + SkASSERT((unsigned)y < (unsigned)fInfo.height()); + return (const uint16_t*)((const char*)this->addr16() + y * fRowBytes + (x << 1)); + } + const uint32_t* addr32(int x, int y) const { + SkASSERT((unsigned)x < (unsigned)fInfo.width()); + SkASSERT((unsigned)y < (unsigned)fInfo.height()); + return (const uint32_t*)((const char*)this->addr32() + y * fRowBytes + (x << 2)); + } + const uint64_t* addr64(int x, int y) const { + SkASSERT((unsigned)x < (unsigned)fInfo.width()); + SkASSERT((unsigned)y < (unsigned)fInfo.height()); + return (const uint64_t*)((const char*)this->addr64() + y * fRowBytes + (x << 3)); + } + const uint16_t* addrF16(int x, int y) const { + SkASSERT(kRGBA_F16_SkColorType == fInfo.colorType()); + return reinterpret_cast(this->addr64(x, y)); + } + + // Writable versions + + void* writable_addr() const { return const_cast(fPixels); } + void* writable_addr(int x, int y) const { + return const_cast(this->addr(x, y)); + } + uint8_t* writable_addr8(int x, int y) const { + return const_cast(this->addr8(x, y)); + } + uint16_t* writable_addr16(int x, int y) const { + return const_cast(this->addr16(x, y)); + } + uint32_t* writable_addr32(int x, int y) const { + return const_cast(this->addr32(x, y)); + } + uint64_t* writable_addr64(int x, int y) const { + return const_cast(this->addr64(x, y)); + } + uint16_t* writable_addrF16(int x, int y) const { + return reinterpret_cast(writable_addr64(x, y)); + } + + // copy methods + + bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes, + int srcX, int srcY) const; + bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes) const { + return this->readPixels(dstInfo, dstPixels, dstRowBytes, 0, 0); + } + bool readPixels(const SkPixmap& dst, int srcX, int srcY) const { + return this->readPixels(dst.info(), dst.writable_addr(), dst.rowBytes(), srcX, srcY); + } + bool readPixels(const SkPixmap& dst) const { + return this->readPixels(dst.info(), dst.writable_addr(), dst.rowBytes(), 0, 0); + } + + /** + * Copy the pixels from this pixmap into the dst pixmap, converting as needed into dst's + * colortype/alphatype. If the conversion cannot be performed, false is returned. + * + * If dst's dimensions differ from the src dimension, the image will be scaled, applying the + * specified filter-quality. + */ + bool scalePixels(const SkPixmap& dst, SkFilterQuality) const; + + /** + * Returns true if pixels were written to (e.g. if colorType is kUnknown_SkColorType, this + * will return false). If subset does not intersect the bounds of this pixmap, returns false. + */ + bool erase(SkColor, const SkIRect& subset) const; + + bool erase(SkColor color) const { return this->erase(color, this->bounds()); } + bool erase(const SkColor4f&, const SkIRect* subset = nullptr) const; + +private: + const void* fPixels; + SkColorTable* fCTable; + size_t fRowBytes; + SkImageInfo fInfo; +}; + +///////////////////////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////////////////////// + +class SK_API SkAutoPixmapUnlock : ::SkNoncopyable { +public: + SkAutoPixmapUnlock() : fUnlockProc(NULL), fIsLocked(false) {} + SkAutoPixmapUnlock(const SkPixmap& pm, void (*unlock)(void*), void* ctx) + : fUnlockProc(unlock), fUnlockContext(ctx), fPixmap(pm), fIsLocked(true) + {} + ~SkAutoPixmapUnlock() { this->unlock(); } + + /** + * Return the currently locked pixmap. Undefined if it has been unlocked. + */ + const SkPixmap& pixmap() const { + SkASSERT(this->isLocked()); + return fPixmap; + } + + bool isLocked() const { return fIsLocked; } + + /** + * Unlocks the pixmap. Can safely be called more than once as it will only call the underlying + * unlock-proc once. + */ + void unlock() { + if (fUnlockProc) { + SkASSERT(fIsLocked); + fUnlockProc(fUnlockContext); + fUnlockProc = NULL; + fIsLocked = false; + } + } + + /** + * If there is a currently locked pixmap, unlock it, then copy the specified pixmap + * and (optional) unlock proc/context. + */ + void reset(const SkPixmap& pm, void (*unlock)(void*), void* ctx); + +private: + void (*fUnlockProc)(void*); + void* fUnlockContext; + SkPixmap fPixmap; + bool fIsLocked; + + friend class SkBitmap; +}; + +#endif diff --git a/libskia/include/core/SkPngChunkReader.h b/libskia/include/core/SkPngChunkReader.h new file mode 100644 index 00000000..0cd6634b --- /dev/null +++ b/libskia/include/core/SkPngChunkReader.h @@ -0,0 +1,45 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkPngChunkReader_DEFINED +#define SkPngChunkReader_DEFINED + +#include "SkTypes.h" +#include "SkRefCnt.h" + +/** + * SkPngChunkReader + * + * Base class for optional callbacks to retrieve meta/chunk data out of a PNG + * encoded image as it is being decoded. + * Used by SkCodec. + */ +class SkPngChunkReader : public SkRefCnt { +public: + /** + * This will be called by the decoder when it sees an unknown chunk. + * + * Use by SkCodec: + * Depending on the location of the unknown chunks, this callback may be + * called by + * - the factory (NewFromStream/NewFromData) + * - getPixels + * - startScanlineDecode + * - the first call to getScanlines/skipScanlines + * The callback may be called from a different thread (e.g. if the SkCodec + * is passed to another thread), and it may be called multiple times, if + * the SkCodec is used multiple times. + * + * @param tag Name for this type of chunk. + * @param data Data to be interpreted by the subclass. + * @param length Number of bytes of data in the chunk. + * @return true to continue decoding, or false to indicate an error, which + * will cause the decoder to not return the image. + */ + virtual bool readChunk(const char tag[], const void* data, size_t length) = 0; +}; +#endif // SkPngChunkReader_DEFINED diff --git a/libskia/include/core/SkPoint.h b/libskia/include/core/SkPoint.h index caf26507..f5ecbab7 100644 --- a/libskia/include/core/SkPoint.h +++ b/libskia/include/core/SkPoint.h @@ -11,6 +11,28 @@ #include "SkMath.h" #include "SkScalar.h" +/** \struct SkIPoint16 + + SkIPoint holds two 16 bit integer coordinates +*/ +struct SkIPoint16 { + int16_t fX, fY; + + static SkIPoint16 Make(int x, int y) { + SkIPoint16 pt; + pt.set(x, y); + return pt; + } + + int16_t x() const { return fX; } + int16_t y() const { return fY; } + + void set(int x, int y) { + fX = SkToS16(x); + fY = SkToS16(y); + } +}; + /** \struct SkIPoint SkIPoint holds two 32 bit integer coordinates @@ -190,7 +212,16 @@ struct SK_API SkPoint { v[2].set(r, b); v[3].set(r, t); } - void setRectFan(SkScalar l, SkScalar t, SkScalar r, SkScalar b, size_t stride); + + void setRectFan(SkScalar l, SkScalar t, SkScalar r, SkScalar b, size_t stride) { + SkASSERT(stride >= sizeof(SkPoint)); + + ((SkPoint*)((intptr_t)this + 0 * stride))->set(l, t); + ((SkPoint*)((intptr_t)this + 1 * stride))->set(l, b); + ((SkPoint*)((intptr_t)this + 2 * stride))->set(r, b); + ((SkPoint*)((intptr_t)this + 3 * stride))->set(r, t); + } + static void Offset(SkPoint points[], int count, const SkPoint& offset) { Offset(points, count, offset.fX, offset.fY); @@ -227,25 +258,25 @@ struct SK_API SkPoint { /** Set the point (vector) to be unit-length in the same direction as it already points. If the point has a degenerate length (i.e. nearly 0) - then return false and do nothing; otherwise return true. + then set it to (0,0) and return false; otherwise return true. */ bool normalize(); /** Set the point (vector) to be unit-length in the same direction as the x,y params. If the vector (x,y) has a degenerate length (i.e. nearly 0) - then return false and do nothing, otherwise return true. + then set it to (0,0) and return false, otherwise return true. */ bool setNormalize(SkScalar x, SkScalar y); /** Scale the point (vector) to have the specified length, and return that length. If the original length is degenerately small (nearly zero), - do nothing and return false, otherwise return true. + set it to (0,0) and return false, otherwise return true. */ bool setLength(SkScalar length); /** Set the point (vector) to have the specified length in the same direction as (x,y). If the vector (x,y) has a degenerate length - (i.e. nearly 0) then return false and do nothing, otherwise return true. + (i.e. nearly 0) then set it to (0,0) and return false, otherwise return true. */ bool setLength(SkScalar x, SkScalar y, SkScalar length); @@ -317,6 +348,16 @@ struct SK_API SkPoint { fY -= v.fY; } + SkPoint operator*(SkScalar scale) const { + return Make(fX * scale, fY * scale); + } + + SkPoint& operator*=(SkScalar scale) { + fX *= scale; + fY *= scale; + return *this; + } + /** * Returns true if both X and Y are finite (not infinity or NaN) */ @@ -326,11 +367,11 @@ struct SK_API SkPoint { accum *= fY; // accum is either NaN or it is finite (zero). - SkASSERT(0 == accum || !(accum == accum)); + SkASSERT(0 == accum || SkScalarIsNaN(accum)); // value==value will be true iff value is not NaN // TODO: is it faster to say !accum or accum==accum? - return accum == accum; + return !SkScalarIsNaN(accum); } /** @@ -392,7 +433,7 @@ struct SK_API SkPoint { static SkScalar Length(SkScalar x, SkScalar y); /** Normalize pt, returning its previous length. If the prev length is too - small (degenerate), return 0 and leave pt unchanged. This uses the same + small (degenerate), set pt to (0,0) and return 0. This uses the same tolerance as CanNormalize. Note that this method may be significantly more expensive than @@ -411,13 +452,13 @@ struct SK_API SkPoint { /** Returns the dot product of a and b, treating them as 2D vectors */ static SkScalar DotProduct(const SkPoint& a, const SkPoint& b) { - return SkScalarMul(a.fX, b.fX) + SkScalarMul(a.fY, b.fY); + return a.fX * b.fX + a.fY * b.fY; } /** Returns the cross product of a and b, treating them as 2D vectors */ static SkScalar CrossProduct(const SkPoint& a, const SkPoint& b) { - return SkScalarMul(a.fX, b.fY) - SkScalarMul(a.fY, b.fX); + return a.fX * b.fY - a.fY * b.fX; } SkScalar cross(const SkPoint& vec) const { @@ -435,7 +476,7 @@ struct SK_API SkPoint { SkScalar distanceToSqd(const SkPoint& pt) const { SkScalar dx = fX - pt.fX; SkScalar dy = fY - pt.fY; - return SkScalarMul(dx, dx) + SkScalarMul(dy, dy); + return dx * dx + dy * dy; } /** @@ -508,4 +549,8 @@ struct SK_API SkPoint { typedef SkPoint SkVector; +static inline bool SkPointsAreFinite(const SkPoint array[], int count) { + return SkScalarsAreFinite(&array[0].fX, count << 1); +} + #endif diff --git a/libskia/include/core/SkPoint3.h b/libskia/include/core/SkPoint3.h new file mode 100644 index 00000000..af24a8df --- /dev/null +++ b/libskia/include/core/SkPoint3.h @@ -0,0 +1,124 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkPoint3_DEFINED +#define SkPoint3_DEFINED + +#include "SkScalar.h" + +struct SK_API SkPoint3 { + SkScalar fX, fY, fZ; + + static SkPoint3 Make(SkScalar x, SkScalar y, SkScalar z) { + SkPoint3 pt; + pt.set(x, y, z); + return pt; + } + + SkScalar x() const { return fX; } + SkScalar y() const { return fY; } + SkScalar z() const { return fZ; } + + void set(SkScalar x, SkScalar y, SkScalar z) { fX = x; fY = y; fZ = z; } + + friend bool operator==(const SkPoint3& a, const SkPoint3& b) { + return a.fX == b.fX && a.fY == b.fY && a.fZ == b.fZ; + } + + friend bool operator!=(const SkPoint3& a, const SkPoint3& b) { + return !(a == b); + } + + /** Returns the Euclidian distance from (0,0,0) to (x,y,z) + */ + static SkScalar Length(SkScalar x, SkScalar y, SkScalar z); + + /** Return the Euclidian distance from (0,0,0) to the point + */ + SkScalar length() const { return SkPoint3::Length(fX, fY, fZ); } + + /** Set the point (vector) to be unit-length in the same direction as it + already points. If the point has a degenerate length (i.e., nearly 0) + then set it to (0,0,0) and return false; otherwise return true. + */ + bool normalize(); + + /** Return a new point whose X, Y and Z coordinates are scaled. + */ + SkPoint3 makeScale(SkScalar scale) const { + SkPoint3 p; + p.set(scale * fX, scale * fY, scale * fZ); + return p; + } + + /** Scale the point's coordinates by scale. + */ + void scale(SkScalar value) { + fX *= value; + fY *= value; + fZ *= value; + } + + /** Return a new point whose X, Y and Z coordinates are the negative of the + original point's + */ + SkPoint3 operator-() const { + SkPoint3 neg; + neg.fX = -fX; + neg.fY = -fY; + neg.fZ = -fZ; + return neg; + } + + /** Returns a new point whose coordinates are the difference between + a and b (i.e., a - b) + */ + friend SkPoint3 operator-(const SkPoint3& a, const SkPoint3& b) { + SkPoint3 v; + v.set(a.fX - b.fX, a.fY - b.fY, a.fZ - b.fZ); + return v; + } + + /** Returns a new point whose coordinates are the sum of a and b (a + b) + */ + friend SkPoint3 operator+(const SkPoint3& a, const SkPoint3& b) { + SkPoint3 v; + v.set(a.fX + b.fX, a.fY + b.fY, a.fZ + b.fZ); + return v; + } + + /** Add v's coordinates to the point's + */ + void operator+=(const SkPoint3& v) { + fX += v.fX; + fY += v.fY; + fZ += v.fZ; + } + + /** Subtract v's coordinates from the point's + */ + void operator-=(const SkPoint3& v) { + fX -= v.fX; + fY -= v.fY; + fZ -= v.fZ; + } + + /** Returns the dot product of a and b, treating them as 3D vectors + */ + static SkScalar DotProduct(const SkPoint3& a, const SkPoint3& b) { + return a.fX * b.fX + a.fY * b.fY + a.fZ * b.fZ; + } + + SkScalar dot(const SkPoint3& vec) const { + return DotProduct(*this, vec); + } +}; + +typedef SkPoint3 SkVector3; +typedef SkPoint3 SkColor3f; + +#endif diff --git a/libskia/include/core/SkPostConfig.h b/libskia/include/core/SkPostConfig.h index 2156519b..c34397cd 100644 --- a/libskia/include/core/SkPostConfig.h +++ b/libskia/include/core/SkPostConfig.h @@ -5,13 +5,23 @@ * found in the LICENSE file. */ +// IWYU pragma: private, include "SkTypes.h" + #ifndef SkPostConfig_DEFINED #define SkPostConfig_DEFINED -#if defined(SK_BUILD_FOR_WIN32) || defined(SK_BUILD_FOR_WINCE) +#if defined(SK_BUILD_FOR_WIN32) # define SK_BUILD_FOR_WIN #endif +#if !defined(SK_DEBUG) && !defined(SK_RELEASE) + #ifdef NDEBUG + #define SK_RELEASE + #else + #define SK_DEBUG + #endif +#endif + #if defined(SK_DEBUG) && defined(SK_RELEASE) # error "cannot define both SK_DEBUG and SK_RELEASE" #elif !defined(SK_DEBUG) && !defined(SK_RELEASE) @@ -24,13 +34,12 @@ /** * Matrix calculations may be float or double. - * The default is double, as that is faster given our impl uses doubles - * for intermediate calculations. + * The default is float, as that's what Chromium's using. */ #if defined(SK_MSCALAR_IS_DOUBLE) && defined(SK_MSCALAR_IS_FLOAT) # error "cannot define both SK_MSCALAR_IS_DOUBLE and SK_MSCALAR_IS_FLOAT" #elif !defined(SK_MSCALAR_IS_DOUBLE) && !defined(SK_MSCALAR_IS_FLOAT) -# define SK_MSCALAR_IS_DOUBLE +# define SK_MSCALAR_IS_FLOAT #endif #if defined(SK_CPU_LENDIAN) && defined(SK_CPU_BENDIAN) @@ -68,6 +77,14 @@ # endif #endif +#if defined(_MSC_VER) && SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2 + #define SK_VECTORCALL __vectorcall +#elif defined(SK_CPU_ARM32) && defined(SK_ARM_HAS_NEON) + #define SK_VECTORCALL __attribute__((pcs("aapcs-vfp"))) +#else + #define SK_VECTORCALL +#endif + #if !defined(SK_SUPPORT_GPU) # define SK_SUPPORT_GPU 1 #endif @@ -88,76 +105,15 @@ # endif #endif -#if defined(SK_ZLIB_INCLUDE) && defined(SK_SYSTEM_ZLIB) -# error "cannot define both SK_ZLIB_INCLUDE and SK_SYSTEM_ZLIB" -#elif defined(SK_ZLIB_INCLUDE) || defined(SK_SYSTEM_ZLIB) -# define SK_HAS_ZLIB -#endif - /////////////////////////////////////////////////////////////////////////////// -#ifndef SkNEW -# define SkNEW(type_name) (new type_name) -# define SkNEW_ARGS(type_name, args) (new type_name args) -# define SkNEW_ARRAY(type_name, count) (new type_name[(count)]) -# define SkNEW_PLACEMENT(buf, type_name) (new (buf) type_name) -# define SkNEW_PLACEMENT_ARGS(buf, type_name, args) (new (buf) type_name args) -# define SkDELETE(obj) (delete (obj)) -# define SkDELETE_ARRAY(array) (delete[] (array)) -#endif +// TODO(mdempsky): Move elsewhere as appropriate. +#include -#ifndef SK_CRASH -# if 1 // set to 0 for infinite loop, which can help connecting gdb -# define SK_CRASH() do { SkNO_RETURN_HINT(); *(int *)(uintptr_t)0xbbadbeef = 0; } while (false) -# else -# define SK_CRASH() do { SkNO_RETURN_HINT(); } while (true) -# endif -#endif - -/////////////////////////////////////////////////////////////////////////////// - -/** - * SK_ENABLE_INST_COUNT controlls printing how many reference counted objects - * are still held on exit. - * Defaults to 1 in DEBUG and 0 in RELEASE. - * FIXME: currently always 0, since it fails if multiple threads run at once - * (see skbug.com/1219 ). - */ -#ifndef SK_ENABLE_INST_COUNT -# ifdef SK_DEBUG -# define SK_ENABLE_INST_COUNT 0 -# else -# define SK_ENABLE_INST_COUNT 0 -# endif -#endif /////////////////////////////////////////////////////////////////////////////// #ifdef SK_BUILD_FOR_WIN -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN -# define WIN32_IS_MEAN_WAS_LOCALLY_DEFINED -# endif -# ifndef NOMINMAX -# define NOMINMAX -# define NOMINMAX_WAS_LOCALLY_DEFINED -# endif -# -# include -# -# ifdef WIN32_IS_MEAN_WAS_LOCALLY_DEFINED -# undef WIN32_IS_MEAN_WAS_LOCALLY_DEFINED -# undef WIN32_LEAN_AND_MEAN -# endif -# ifdef NOMINMAX_WAS_LOCALLY_DEFINED -# undef NOMINMAX_WAS_LOCALLY_DEFINED -# undef NOMINMAX -# endif -# -# ifndef SK_DEBUGBREAK -# define SK_DEBUGBREAK(p) do { if (!(p)) { SkNO_RETURN_HINT(); __debugbreak(); }} while (false) -# endif -# # ifndef SK_A32_SHIFT # define SK_A32_SHIFT 24 # define SK_R32_SHIFT 16 @@ -165,15 +121,24 @@ # define SK_B32_SHIFT 0 # endif # +#endif + +#if defined(GOOGLE3) + void SkDebugfForDumpStackTrace(const char* data, void* unused); + void DumpStackTrace(int skip_count, void w(const char*, void*), void* arg); +# define SK_DUMP_GOOGLE3_STACK() DumpStackTrace(0, SkDebugfForDumpStackTrace, nullptr) #else -# ifdef SK_DEBUG -# include -# ifndef SK_DEBUGBREAK -# define SK_DEBUGBREAK(cond) do { if (cond) break; \ - SkDebugf("%s:%d: failed assertion \"%s\"\n", \ - __FILE__, __LINE__, #cond); SK_CRASH(); } while (false) -# endif -# endif +# define SK_DUMP_GOOGLE3_STACK() +#endif + +#ifndef SK_ABORT +# define SK_ABORT(message) \ + do { \ + SkNO_RETURN_HINT(); \ + SkDebugf("%s:%d: fatal error: \"%s\"\n", __FILE__, __LINE__, message); \ + SK_DUMP_GOOGLE3_STACK(); \ + sk_abort_no_print(); \ + } while (false) #endif /** @@ -225,26 +190,7 @@ SK_ ## C3 ## 32_SHIFT == 24) #endif -////////////////////////////////////////////////////////////////////// - -// TODO: rebaseline as needed so we can remove this flag entirely. -// - all platforms have int64_t now -// - we have slightly different fixed math results because of this check -// since we don't define this for linux/android -#if defined(SK_BUILD_FOR_WIN32) || defined(SK_BUILD_FOR_MAC) -# ifndef SkLONGLONG -# define SkLONGLONG int64_t -# endif -#endif - ////////////////////////////////////////////////////////////////////////////////////////////// -#ifndef SK_BUILD_FOR_WINCE -# include -# include -#else -# define _CMNINTRIN_DECLARE_ONLY -# include "cmnintrin.h" -#endif #if defined SK_DEBUG && defined SK_BUILD_FOR_WIN32 # ifdef free @@ -289,38 +235,27 @@ ////////////////////////////////////////////////////////////////////// -#ifndef SK_OVERRIDE +#if !defined(SK_UNUSED) # if defined(_MSC_VER) -# define SK_OVERRIDE override -# elif defined(__clang__) - // Using __attribute__((override)) on clang does not appear to always work. - // Clang defaults to C++03 and warns about using override. Squelch that. Intentionally no - // push/pop here so all users of SK_OVERRIDE ignore the warning too. This is like passing - // -Wno-c++11-extensions, except that GCC won't die (because it won't see this pragma). -# pragma clang diagnostic ignored "-Wc++11-extensions" -# -# if __has_feature(cxx_override_control) -# define SK_OVERRIDE override -# elif defined(__has_extension) && __has_extension(cxx_override_control) -# define SK_OVERRIDE override -# endif -# endif -# ifndef SK_OVERRIDE -# define SK_OVERRIDE +# define SK_UNUSED __pragma(warning(suppress:4189)) +# else +# define SK_UNUSED SK_ATTRIBUTE(unused) # endif #endif -////////////////////////////////////////////////////////////////////// - -#if !defined(SK_UNUSED) -# define SK_UNUSED SK_ATTRIBUTE(unused) -#endif - #if !defined(SK_ATTR_DEPRECATED) // FIXME: we ignore msg for now... # define SK_ATTR_DEPRECATED(msg) SK_ATTRIBUTE(deprecated) #endif +#if !defined(SK_ATTR_EXTERNALLY_DEPRECATED) +# if !defined(SK_INTERNAL) +# define SK_ATTR_EXTERNALLY_DEPRECATED(msg) SK_ATTR_DEPRECATED(msg) +# else +# define SK_ATTR_EXTERNALLY_DEPRECATED(msg) +# endif +#endif + /** * If your judgment is better than the compiler's (i.e. you've profiled it), * you can use SK_ALWAYS_INLINE to force inlining. E.g. @@ -335,14 +270,29 @@ # endif #endif +/** + * If your judgment is better than the compiler's (i.e. you've profiled it), + * you can use SK_NEVER_INLINE to prevent inlining. + */ +#if !defined(SK_NEVER_INLINE) +# if defined(SK_BUILD_FOR_WIN) +# define SK_NEVER_INLINE __declspec(noinline) +# else +# define SK_NEVER_INLINE SK_ATTRIBUTE(noinline) +# endif +#endif + ////////////////////////////////////////////////////////////////////// -#if defined(__clang__) || defined(__GNUC__) -# define SK_PREFETCH(ptr) __builtin_prefetch(ptr) -# define SK_WRITE_PREFETCH(ptr) __builtin_prefetch(ptr, 1) +#if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE1 + #define SK_PREFETCH(ptr) _mm_prefetch(reinterpret_cast(ptr), _MM_HINT_T0) + #define SK_WRITE_PREFETCH(ptr) _mm_prefetch(reinterpret_cast(ptr), _MM_HINT_T0) +#elif defined(__GNUC__) + #define SK_PREFETCH(ptr) __builtin_prefetch(ptr) + #define SK_WRITE_PREFETCH(ptr) __builtin_prefetch(ptr, 1) #else -# define SK_PREFETCH(ptr) -# define SK_WRITE_PREFETCH(ptr) + #define SK_PREFETCH(ptr) + #define SK_WRITE_PREFETCH(ptr) #endif ////////////////////////////////////////////////////////////////////// @@ -373,22 +323,40 @@ ////////////////////////////////////////////////////////////////////// -#ifndef SK_ATOMICS_PLATFORM_H -# if defined(SK_BUILD_FOR_WIN) -# define SK_ATOMICS_PLATFORM_H "../../src/ports/SkAtomics_win.h" -# elif defined(SK_BUILD_FOR_ANDROID_FRAMEWORK) -# define SK_ATOMICS_PLATFORM_H "../../src/ports/SkAtomics_android.h" +#ifndef SK_EGL +# if defined(SK_BUILD_FOR_ANDROID) +# define SK_EGL 1 # else -# define SK_ATOMICS_PLATFORM_H "../../src/ports/SkAtomics_sync.h" +# define SK_EGL 0 # endif #endif -#ifndef SK_MUTEX_PLATFORM_H -# if defined(SK_BUILD_FOR_WIN) -# define SK_MUTEX_PLATFORM_H "../../src/ports/SkMutex_win.h" -# else -# define SK_MUTEX_PLATFORM_H "../../src/ports/SkMutex_pthread.h" -# endif +////////////////////////////////////////////////////////////////////// + +#if !defined(SK_GAMMA_EXPONENT) + #define SK_GAMMA_EXPONENT (0.0f) // SRGB +#endif + +////////////////////////////////////////////////////////////////////// + +#ifndef GR_TEST_UTILS +# define GR_TEST_UTILS 1 +#endif + +////////////////////////////////////////////////////////////////////// + +#if defined(SK_HISTOGRAM_ENUMERATION) && defined(SK_HISTOGRAM_BOOLEAN) +# define SK_HISTOGRAMS_ENABLED 1 +#else +# define SK_HISTOGRAMS_ENABLED 0 +#endif + +#ifndef SK_HISTOGRAM_BOOLEAN +# define SK_HISTOGRAM_BOOLEAN(name, value) +#endif + +#ifndef SK_HISTOGRAM_ENUMERATION +# define SK_HISTOGRAM_ENUMERATION(name, value, boundary_value) #endif #endif // SkPostConfig_DEFINED diff --git a/libskia/include/core/SkPreConfig.h b/libskia/include/core/SkPreConfig.h index 2aa4d822..0e6f787a 100644 --- a/libskia/include/core/SkPreConfig.h +++ b/libskia/include/core/SkPreConfig.h @@ -1,4 +1,3 @@ - /* * Copyright 2006 The Android Open Source Project * @@ -6,42 +5,33 @@ * found in the LICENSE file. */ +// IWYU pragma: private, include "SkTypes.h" #ifndef SkPreConfig_DEFINED #define SkPreConfig_DEFINED -#ifdef WEBKIT_VERSION_MIN_REQUIRED - #include "config.h" -#endif - // Allows embedders that want to disable macros that take arguments to just // define that symbol to be one of these -// #define SK_NOTHING_ARG1(arg1) #define SK_NOTHING_ARG2(arg1, arg2) #define SK_NOTHING_ARG3(arg1, arg2, arg3) ////////////////////////////////////////////////////////////////////// -#if !defined(SK_BUILD_FOR_ANDROID) && !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_PALM) && !defined(SK_BUILD_FOR_WINCE) && !defined(SK_BUILD_FOR_WIN32) && !defined(SK_BUILD_FOR_UNIX) && !defined(SK_BUILD_FOR_MAC) && !defined(SK_BUILD_FOR_SDL) && !defined(SK_BUILD_FOR_BREW) && !defined(SK_BUILD_FOR_NACL) +#if !defined(SK_BUILD_FOR_ANDROID) && !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_WIN32) && !defined(SK_BUILD_FOR_UNIX) && !defined(SK_BUILD_FOR_MAC) #ifdef __APPLE__ #include "TargetConditionals.h" #endif - #if defined(PALMOS_SDK_VERSION) - #define SK_BUILD_FOR_PALM - #elif defined(UNDER_CE) - #define SK_BUILD_FOR_WINCE - #elif defined(WIN32) + #if defined(_WIN32) || defined(__SYMBIAN32__) #define SK_BUILD_FOR_WIN32 - #elif defined(__SYMBIAN32__) - #define SK_BUILD_FOR_WIN32 - #elif defined(ANDROID) + #elif defined(ANDROID) || defined(__ANDROID__) #define SK_BUILD_FOR_ANDROID - #elif defined(linux) || defined(__FreeBSD__) || defined(__OpenBSD__) || \ - defined(__sun) || defined(__NetBSD__) || defined(__DragonFly__) || \ - defined(__GLIBC__) || defined(__GNU__) + #elif defined(linux) || defined(__linux) || defined(__FreeBSD__) || \ + defined(__OpenBSD__) || defined(__sun) || defined(__NetBSD__) || \ + defined(__DragonFly__) || defined(__Fuchsia__) || \ + defined(__GLIBC__) || defined(__GNU__) || defined(__unix__) #define SK_BUILD_FOR_UNIX #elif TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR #define SK_BUILD_FOR_IOS @@ -62,14 +52,6 @@ ////////////////////////////////////////////////////////////////////// -#if !defined(SK_DEBUG) && !defined(SK_RELEASE) - #ifdef NDEBUG - #define SK_RELEASE - #else - #define SK_DEBUG - #endif -#endif - #ifdef SK_BUILD_FOR_WIN32 #if !defined(SK_RESTRICT) #define SK_RESTRICT __restrict @@ -79,8 +61,6 @@ #endif #endif -////////////////////////////////////////////////////////////////////// - #if !defined(SK_RESTRICT) #define SK_RESTRICT __restrict__ #endif @@ -92,9 +72,19 @@ ////////////////////////////////////////////////////////////////////// #if !defined(SK_CPU_BENDIAN) && !defined(SK_CPU_LENDIAN) - #if defined (__ppc__) || defined(__PPC__) || defined(__ppc64__) \ - || defined(__PPC64__) + #if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) #define SK_CPU_BENDIAN + #elif defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) + #define SK_CPU_LENDIAN + #elif defined(__sparc) || defined(__sparc__) || \ + defined(_POWER) || defined(__powerpc__) || \ + defined(__ppc__) || defined(__hppa) || \ + defined(__PPC__) || defined(__PPC64__) || \ + defined(_MIPSEB) || defined(__ARMEB__) || \ + defined(__s390__) || \ + (defined(__sh__) && defined(__BIG_ENDIAN__)) || \ + (defined(__ia64) && defined(__BIG_ENDIAN__)) + #define SK_CPU_BENDIAN #else #define SK_CPU_LENDIAN #endif @@ -102,6 +92,10 @@ ////////////////////////////////////////////////////////////////////// +#if defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64) + #define SK_CPU_X86 1 +#endif + /** * SK_CPU_SSE_LEVEL * @@ -113,32 +107,56 @@ #define SK_CPU_SSE_LEVEL_SSE2 20 #define SK_CPU_SSE_LEVEL_SSE3 30 #define SK_CPU_SSE_LEVEL_SSSE3 31 +#define SK_CPU_SSE_LEVEL_SSE41 41 +#define SK_CPU_SSE_LEVEL_SSE42 42 +#define SK_CPU_SSE_LEVEL_AVX 51 +#define SK_CPU_SSE_LEVEL_AVX2 52 + +// When targetting iOS and using gyp to generate the build files, it is not +// possible to select files to build depending on the architecture (i.e. it +// is not possible to use hand optimized assembly implementation). In that +// configuration SK_BUILD_NO_OPTS is defined. Remove optimisation then. +#ifdef SK_BUILD_NO_OPTS + #define SK_CPU_SSE_LEVEL 0 +#endif // Are we in GCC? #ifndef SK_CPU_SSE_LEVEL - #if defined(__SSE2__) - #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE2 - #elif defined(__SSE3__) - #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE3 + // These checks must be done in descending order to ensure we set the highest + // available SSE level. + #if defined(__AVX2__) + #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_AVX2 + #elif defined(__AVX__) + #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_AVX + #elif defined(__SSE4_2__) + #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE42 + #elif defined(__SSE4_1__) + #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE41 #elif defined(__SSSE3__) #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSSE3 + #elif defined(__SSE3__) + #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE3 + #elif defined(__SSE2__) + #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE2 #endif #endif // Are we in VisualStudio? #ifndef SK_CPU_SSE_LEVEL - #if _M_IX86_FP == 1 - #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE1 - #elif _M_IX86_FP >= 2 - #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE2 - #endif -#endif - -// 64bit intel guarantees at least SSE2 -#if defined(__x86_64__) || defined(_WIN64) - #if !defined(SK_CPU_SSE_LEVEL) || (SK_CPU_SSE_LEVEL < SK_CPU_SSE_LEVEL_SSE2) - #undef SK_CPU_SSE_LEVEL - #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE2 + // These checks must be done in descending order to ensure we set the highest + // available SSE level. 64-bit intel guarantees at least SSE2 support. + #if defined(__AVX2__) + #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_AVX2 + #elif defined(__AVX__) + #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_AVX + #elif defined(_M_X64) || defined(_M_AMD64) + #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE2 + #elif defined(_M_IX86_FP) + #if _M_IX86_FP >= 2 + #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE2 + #elif _M_IX86_FP == 1 + #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE1 + #endif #endif #endif @@ -146,7 +164,7 @@ // ARM defines #if defined(__arm__) && (!defined(__APPLE__) || !TARGET_IPHONE_SIMULATOR) - #define SK_CPU_ARM + #define SK_CPU_ARM32 #if defined(__GNUC__) #if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \ @@ -167,33 +185,44 @@ #else #define SK_ARM_ARCH 3 #endif - - #if defined(__thumb2__) && (SK_ARM_ARCH >= 6) \ - || !defined(__thumb__) && ((SK_ARM_ARCH > 5) || defined(__ARM_ARCH_5E__) \ - || defined(__ARM_ARCH_5TE__) || defined(__ARM_ARCH_5TEJ__)) - #define SK_ARM_HAS_EDSP - #endif #endif #endif +#if defined(__aarch64__) && !defined(SK_BUILD_NO_OPTS) + #define SK_CPU_ARM64 +#endif + +// All 64-bit ARM chips have NEON. Many 32-bit ARM chips do too. +#if !defined(SK_ARM_HAS_NEON) && !defined(SK_BUILD_NO_OPTS) && (defined(__ARM_NEON__) || defined(__ARM_NEON)) + #define SK_ARM_HAS_NEON +#endif + +// Really this __APPLE__ check shouldn't be necessary, but it seems that Apple's Clang defines +// __ARM_FEATURE_CRC32 for -arch arm64, even though their chips don't support those instructions! +#if defined(__ARM_FEATURE_CRC32) && !defined(__APPLE__) + #define SK_ARM_HAS_CRC32 +#endif + ////////////////////////////////////////////////////////////////////// #if !defined(SKIA_IMPLEMENTATION) #define SKIA_IMPLEMENTATION 0 #endif -#if defined(SKIA_DLL) - #if defined(WIN32) - #if SKIA_IMPLEMENTATION - #define SK_API __declspec(dllexport) +#if !defined(SK_API) + #if defined(SKIA_DLL) + #if defined(_MSC_VER) + #if SKIA_IMPLEMENTATION + #define SK_API __declspec(dllexport) + #else + #define SK_API __declspec(dllimport) + #endif #else - #define SK_API __declspec(dllimport) + #define SK_API __attribute__((visibility("default"))) #endif #else - #define SK_API __attribute__((visibility("default"))) + #define SK_API #endif -#else - #define SK_API #endif ////////////////////////////////////////////////////////////////////// diff --git a/libskia/include/core/SkRRect.h b/libskia/include/core/SkRRect.h index 66c433f4..3b691aab 100644 --- a/libskia/include/core/SkRRect.h +++ b/libskia/include/core/SkRRect.h @@ -16,7 +16,6 @@ class SkMatrix; // Path forward: // core work -// add validate method (all radii positive, all radii sums < rect size, etc.) // add contains(SkRect&) - for clip stack // add contains(SkRRect&) - for clip stack // add heart rect computation (max rect inside RR) @@ -26,15 +25,9 @@ class SkMatrix; // use growToInclude to fit skp round rects & generate stats (RRs vs. real paths) // check on # of rectorus's the RRs could handle // rendering work -// add entry points (clipRRect, drawRRect) - plumb down to SkBaseDevice -// update SkPath.addRRect() to take an SkRRect - only use quads -// -- alternatively add addRRectToPath here +// update SkPath.addRRect() to only use quads // add GM and bench -// clipping opt -// update SkClipStack to perform logic with RRs // further out -// add RR rendering shader to Ganesh (akin to cicle drawing code) -// - only for simple RRs // detect and triangulate RRectorii rather than falling back to SW in Ganesh // @@ -53,14 +46,15 @@ class SkMatrix; */ class SK_API SkRRect { public: + SkRRect() { /* unititialized */ } + SkRRect(const SkRRect&) = default; + SkRRect& operator=(const SkRRect&) = default; + /** * Enum to capture the various possible subtypes of RR. Accessed * by type(). The subtypes become progressively less restrictive. */ enum Type { - // !< Internal indicator that the sub type must be computed. - kUnknown_Type = -1, - // !< The RR is empty kEmpty_Type, @@ -77,6 +71,14 @@ class SK_API SkRRect { //!< the curves) nor a rect (i.e., both radii are non-zero) kSimple_Type, + //!< The RR is non-empty and the two left x radii are equal, the two top + //!< y radii are equal, and the same for the right and bottom but it is + //!< neither an rect, oval, nor a simple RR. It is called "nine patch" + //!< because the centers of the corner ellipses form an axis aligned + //!< rect with edges that divide the RR into an 9 rectangular patches: + //!< an interior patch, four edge patches, and four corner patches. + kNinePatch_Type, + //!< A fully general (non-empty) RR. Some of the x and/or y radii are //!< different from the others and there must be one corner where //!< both radii are non-zero. @@ -87,13 +89,8 @@ class SK_API SkRRect { * Returns the RR's sub type. */ Type getType() const { - SkDEBUGCODE(this->validate();) - - if (kUnknown_Type == fType) { - this->computeType(); - } - SkASSERT(kUnknown_Type != fType); - return fType; + SkASSERT(this->isValid()); + return static_cast(fType); } Type type() const { return this->getType(); } @@ -102,8 +99,19 @@ class SK_API SkRRect { inline bool isRect() const { return kRect_Type == this->getType(); } inline bool isOval() const { return kOval_Type == this->getType(); } inline bool isSimple() const { return kSimple_Type == this->getType(); } + // TODO: should isSimpleCircular & isCircle take a tolerance? This could help + // instances where the mapping to device space is noisy. + inline bool isSimpleCircular() const { + return this->isSimple() && SkScalarNearlyEqual(fRadii[0].fX, fRadii[0].fY); + } + inline bool isCircle() const { + return this->isOval() && SkScalarNearlyEqual(fRadii[0].fX, fRadii[0].fY); + } + inline bool isNinePatch() const { return kNinePatch_Type == this->getType(); } inline bool isComplex() const { return kComplex_Type == this->getType(); } + bool allCornersCircular() const; + SkScalar width() const { return fRect.width(); } SkScalar height() const { return fRect.height(); } @@ -115,23 +123,49 @@ class SK_API SkRRect { memset(fRadii, 0, sizeof(fRadii)); fType = kEmpty_Type; - SkDEBUGCODE(this->validate();) + SkASSERT(this->isValid()); } /** * Set this RR to match the supplied rect. All radii will be 0. */ void setRect(const SkRect& rect) { - if (rect.isEmpty()) { + fRect = rect; + fRect.sort(); + + if (fRect.isEmpty()) { this->setEmpty(); return; } - fRect = rect; memset(fRadii, 0, sizeof(fRadii)); fType = kRect_Type; - SkDEBUGCODE(this->validate();) + SkASSERT(this->isValid()); + } + + static SkRRect MakeEmpty() { + SkRRect rr; + rr.setEmpty(); + return rr; + } + + static SkRRect MakeRect(const SkRect& r) { + SkRRect rr; + rr.setRect(r); + return rr; + } + + static SkRRect MakeOval(const SkRect& oval) { + SkRRect rr; + rr.setOval(oval); + return rr; + } + + static SkRRect MakeRectXY(const SkRect& rect, SkScalar xRad, SkScalar yRad) { + SkRRect rr; + rr.setRectXY(rect, xRad, yRad); + return rr; } /** @@ -139,21 +173,23 @@ class SK_API SkRRect { * width and all y radii will equal half the height. */ void setOval(const SkRect& oval) { - if (oval.isEmpty()) { + fRect = oval; + fRect.sort(); + + if (fRect.isEmpty()) { this->setEmpty(); return; } - SkScalar xRad = SkScalarHalf(oval.width()); - SkScalar yRad = SkScalarHalf(oval.height()); + SkScalar xRad = SkScalarHalf(fRect.width()); + SkScalar yRad = SkScalarHalf(fRect.height()); - fRect = oval; for (int i = 0; i < 4; ++i) { fRadii[i].set(xRad, yRad); } fType = kOval_Type; - SkDEBUGCODE(this->validate();) + SkASSERT(this->isValid()); } /** @@ -161,6 +197,12 @@ class SK_API SkRRect { */ void setRectXY(const SkRect& rect, SkScalar xRad, SkScalar yRad); + /** + * Initialize the rr with one radius per-side. + */ + void setNinePatch(const SkRect& rect, SkScalar leftRad, SkScalar topRad, + SkScalar rightRad, SkScalar bottomRad); + /** * Initialize the RR with potentially different radii for all four corners. */ @@ -228,13 +270,24 @@ class SK_API SkRRect { this->inset(-dx, -dy, this); } + /** + * Translate the rrect by (dx, dy). + */ + void offset(SkScalar dx, SkScalar dy) { + fRect.offset(dx, dy); + } + + SkRRect SK_WARN_UNUSED_RESULT makeOffset(SkScalar dx, SkScalar dy) const { + return SkRRect(fRect.makeOffset(dx, dy), fRadii, fType); + } + /** * Returns true if 'rect' is wholy inside the RR, and both * are not empty. */ bool contains(const SkRect& rect) const; - SkDEBUGCODE(void validate() const;) + bool isValid() const; enum { kSizeInMemory = 12 * sizeof(SkScalar) @@ -271,16 +324,27 @@ class SK_API SkRRect { */ bool transform(const SkMatrix& matrix, SkRRect* dst) const; + void dump(bool asHex) const; + void dump() const { this->dump(false); } + void dumpHex() const { this->dump(true); } + private: + SkRRect(const SkRect& rect, const SkVector radii[4], int32_t type) + : fRect(rect) + , fRadii{radii[0], radii[1], radii[2], radii[3]} + , fType(type) {} + SkRect fRect; // Radii order is UL, UR, LR, LL. Use Corner enum to index into fRadii[] SkVector fRadii[4]; - mutable Type fType; + // use an explicitly sized type so we're sure the class is dense (no uninitialized bytes) + int32_t fType; // TODO: add padding so we can use memcpy for flattening and not copy // uninitialized data - void computeType() const; + void computeType(); bool checkCornerContainment(SkScalar x, SkScalar y) const; + void scaleRadii(); // to access fRadii directly friend class SkPath; diff --git a/libskia/include/core/SkRSXform.h b/libskia/include/core/SkRSXform.h new file mode 100644 index 00000000..7af6e67c --- /dev/null +++ b/libskia/include/core/SkRSXform.h @@ -0,0 +1,67 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkRSXform_DEFINED +#define SkRSXform_DEFINED + +#include "SkScalar.h" + +/** + * A compressed form of a rotation+scale matrix. + * + * [ fSCos -fSSin fTx ] + * [ fSSin fSCos fTy ] + * [ 0 0 1 ] + */ +struct SkRSXform { + static SkRSXform Make(SkScalar scos, SkScalar ssin, SkScalar tx, SkScalar ty) { + SkRSXform xform = { scos, ssin, tx, ty }; + return xform; + } + + /* + * Initialize a new xform based on the scale, rotation (in radians), final tx,ty location + * and anchor-point ax,ay within the src quad. + * + * Note: the anchor point is not normalized (e.g. 0...1) but is in pixels of the src image. + */ + static SkRSXform MakeFromRadians(SkScalar scale, SkScalar radians, SkScalar tx, SkScalar ty, + SkScalar ax, SkScalar ay) { + const SkScalar s = SkScalarSin(radians) * scale; + const SkScalar c = SkScalarCos(radians) * scale; + return Make(c, s, tx + -c * ax + s * ay, ty + -s * ax - c * ay); + } + + SkScalar fSCos; + SkScalar fSSin; + SkScalar fTx; + SkScalar fTy; + + bool rectStaysRect() const { + return 0 == fSCos || 0 == fSSin; + } + + void setIdentity() { + fSCos = 1; + fSSin = fTx = fTy = 0; + } + + void set(SkScalar scos, SkScalar ssin, SkScalar tx, SkScalar ty) { + fSCos = scos; + fSSin = ssin; + fTx = tx; + fTy = ty; + } + + void toQuad(SkScalar width, SkScalar height, SkPoint quad[4]) const; + void toQuad(const SkSize& size, SkPoint quad[4]) const { + this->toQuad(size.width(), size.height(), quad); + } +}; + +#endif + diff --git a/libskia/include/core/SkRWBuffer.h b/libskia/include/core/SkRWBuffer.h new file mode 100644 index 00000000..451933f3 --- /dev/null +++ b/libskia/include/core/SkRWBuffer.h @@ -0,0 +1,107 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkRWBuffer_DEFINED +#define SkRWBuffer_DEFINED + +#include "SkRefCnt.h" + +struct SkBufferBlock; +struct SkBufferHead; +class SkRWBuffer; +class SkStreamAsset; + +/** + * Contains a read-only, thread-sharable block of memory. To access the memory, the caller must + * instantiate a local iterator, as the memory is stored in 1 or more contiguous blocks. + */ +class SK_API SkROBuffer : public SkRefCnt { +public: + /** + * Return the logical length of the data owned/shared by this buffer. It may be stored in + * multiple contiguous blocks, accessible via the iterator. + */ + size_t size() const { return fAvailable; } + + class SK_API Iter { + public: + Iter(const SkROBuffer*); + + void reset(const SkROBuffer*); + + /** + * Return the current continuous block of memory, or nullptr if the iterator is exhausted + */ + const void* data() const; + + /** + * Returns the number of bytes in the current continguous block of memory, or 0 if the + * iterator is exhausted. + */ + size_t size() const; + + /** + * Advance to the next contiguous block of memory, returning true if there is another + * block, or false if the iterator is exhausted. + */ + bool next(); + + private: + const SkBufferBlock* fBlock; + size_t fRemaining; + const SkROBuffer* fBuffer; + }; + +private: + SkROBuffer(const SkBufferHead* head, size_t available, const SkBufferBlock* fTail); + virtual ~SkROBuffer(); + + const SkBufferHead* fHead; + const size_t fAvailable; + const SkBufferBlock* fTail; + + friend class SkRWBuffer; +}; + +/** + * Accumulates bytes of memory that are "appended" to it, growing internal storage as needed. + * The growth is done such that at any time in the writer's thread, an RBuffer or StreamAsset + * can be snapped off (and safely passed to another thread). The RBuffer/StreamAsset snapshot + * can see the previously stored bytes, but will be unaware of any future writes. + */ +class SK_API SkRWBuffer { +public: + SkRWBuffer(size_t initialCapacity = 0); + ~SkRWBuffer(); + + size_t size() const { return fTotalUsed; } + + /** + * Append |length| bytes from |buffer|. + * + * If the caller knows in advance how much more data they are going to append, they can + * pass a |reserve| hint (representing the number of upcoming bytes *in addition* to the + * current append), to minimize the number of internal allocations. + */ + void append(const void* buffer, size_t length, size_t reserve = 0); + + SkROBuffer* newRBufferSnapshot() const; + SkStreamAsset* newStreamSnapshot() const; + +#ifdef SK_DEBUG + void validate() const; +#else + void validate() const {} +#endif + +private: + SkBufferHead* fHead; + SkBufferBlock* fTail; + size_t fTotalUsed; +}; + +#endif diff --git a/libskia/include/core/SkRasterizer.h b/libskia/include/core/SkRasterizer.h index 6e6224ef..1881ccef 100644 --- a/libskia/include/core/SkRasterizer.h +++ b/libskia/include/core/SkRasterizer.h @@ -20,10 +20,6 @@ struct SkIRect; class SK_API SkRasterizer : public SkFlattenable { public: - SK_DECLARE_INST_COUNT(SkRasterizer) - - SkRasterizer() {} - /** Turn the path into a mask, respecting the specified local->device matrix. */ bool rasterize(const SkPath& path, const SkMatrix& matrix, @@ -33,8 +29,7 @@ class SK_API SkRasterizer : public SkFlattenable { SK_DEFINE_FLATTENABLE_TYPE(SkRasterizer) protected: - SkRasterizer(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {} - + SkRasterizer() {} virtual bool onRasterize(const SkPath& path, const SkMatrix& matrix, const SkIRect* clipBounds, SkMask* mask, SkMask::CreateMode mode) const; diff --git a/libskia/include/core/SkRect.h b/libskia/include/core/SkRect.h index 397e4a03..27a648fe 100644 --- a/libskia/include/core/SkRect.h +++ b/libskia/include/core/SkRect.h @@ -1,4 +1,3 @@ - /* * Copyright 2006 The Android Open Source Project * @@ -6,13 +5,14 @@ * found in the LICENSE file. */ - #ifndef SkRect_DEFINED #define SkRect_DEFINED #include "SkPoint.h" #include "SkSize.h" +struct SkRect; + /** \struct SkIRect SkIRect holds four 32 bit integer coordinates for a rectangle @@ -77,6 +77,8 @@ struct SK_API SkIRect { */ int height() const { return fBottom - fTop; } + SkISize size() const { return SkISize::Make(this->width(), this->height()); } + /** * Since the center of an integer rect may fall on a factional value, this * method is defined to return (right + left) >> 1. @@ -157,6 +159,27 @@ struct SK_API SkIRect { fRight = fBottom = SK_MinS32; } + /** + * Return a new IRect, built as an offset of this rect. + */ + SkIRect makeOffset(int32_t dx, int32_t dy) const { + return MakeLTRB(fLeft + dx, fTop + dy, fRight + dx, fBottom + dy); + } + + /** + * Return a new IRect, built as an inset of this rect. + */ + SkIRect makeInset(int32_t dx, int32_t dy) const { + return MakeLTRB(fLeft + dx, fTop + dy, fRight - dx, fBottom - dy); + } + + /** + * Return a new Rect, built as an outset of this rect. + */ + SkIRect makeOutset(int32_t dx, int32_t dy) const { + return MakeLTRB(fLeft - dx, fTop - dy, fRight + dx, fBottom + dy); + } + /** Offset set the rectangle by adding dx to its left and right, and adding dy to its top and bottom. */ @@ -230,6 +253,10 @@ struct SK_API SkIRect { fRight >= r.fRight && fBottom >= r.fBottom; } + /** Returns true if the specified rectangle r is inside or equal to this rectangle. + */ + bool contains(const SkRect& r) const; + /** Return true if this rectangle contains the specified rectangle. For speed, this method does not check if either this or the specified rectangles are empty, and if either is, its return value is undefined. @@ -253,8 +280,7 @@ struct SK_API SkIRect { intersection, otherwise return false and do not change this rectangle. If either rectangle is empty, do nothing and return false. */ - bool intersect(const SkIRect& r) { - SkASSERT(&r); + bool SK_WARN_UNUSED_RESULT intersect(const SkIRect& r) { return this->intersect(r.fLeft, r.fTop, r.fRight, r.fBottom); } @@ -262,8 +288,7 @@ struct SK_API SkIRect { that intersection, otherwise return false and do not change this rectangle. If either rectangle is empty, do nothing and return false. */ - bool intersect(const SkIRect& a, const SkIRect& b) { - SkASSERT(&a && &b); + bool SK_WARN_UNUSED_RESULT intersect(const SkIRect& a, const SkIRect& b) { if (!a.isEmpty() && !b.isEmpty() && a.fLeft < b.fRight && b.fLeft < a.fRight && @@ -283,8 +308,7 @@ struct SK_API SkIRect { If either is, then the return result is undefined. In the debug build, we assert that both rectangles are non-empty. */ - bool intersectNoEmptyCheck(const SkIRect& a, const SkIRect& b) { - SkASSERT(&a && &b); + bool SK_WARN_UNUSED_RESULT intersectNoEmptyCheck(const SkIRect& a, const SkIRect& b) { SkASSERT(!a.isEmpty() && !b.isEmpty()); if (a.fLeft < b.fRight && b.fLeft < a.fRight && @@ -303,7 +327,8 @@ struct SK_API SkIRect { otherwise return false and do not change this rectangle. If either rectangle is empty, do nothing and return false. */ - bool intersect(int32_t left, int32_t top, int32_t right, int32_t bottom) { + bool SK_WARN_UNUSED_RESULT intersect(int32_t left, int32_t top, + int32_t right, int32_t bottom) { if (left < right && top < bottom && !this->isEmpty() && fLeft < right && left < fRight && fTop < bottom && top < fBottom) { if (fLeft < left) fLeft = left; @@ -319,8 +344,8 @@ struct SK_API SkIRect { */ static bool Intersects(const SkIRect& a, const SkIRect& b) { return !a.isEmpty() && !b.isEmpty() && // check for empties - a.fLeft < b.fRight && b.fLeft < a.fRight && - a.fTop < b.fBottom && b.fTop < a.fBottom; + a.fLeft < b.fRight && b.fLeft < a.fRight && + a.fTop < b.fBottom && b.fTop < a.fBottom; } /** @@ -365,10 +390,8 @@ struct SK_API SkIRect { struct SK_API SkRect { SkScalar fLeft, fTop, fRight, fBottom; - static SkRect SK_WARN_UNUSED_RESULT MakeEmpty() { - SkRect r; - r.setEmpty(); - return r; + static constexpr SkRect SK_WARN_UNUSED_RESULT MakeEmpty() { + return SkRect{0, 0, 0, 0}; } static SkRect SK_WARN_UNUSED_RESULT MakeLargest() { @@ -383,16 +406,21 @@ struct SK_API SkRect { return r; } + static SkRect SK_WARN_UNUSED_RESULT MakeIWH(int w, int h) { + SkRect r; + r.set(0, 0, SkIntToScalar(w), SkIntToScalar(h)); + return r; + } + static SkRect SK_WARN_UNUSED_RESULT MakeSize(const SkSize& size) { SkRect r; r.set(0, 0, size.width(), size.height()); return r; } - static SkRect SK_WARN_UNUSED_RESULT MakeLTRB(SkScalar l, SkScalar t, SkScalar r, SkScalar b) { - SkRect rect; - rect.set(l, t, r, b); - return rect; + static constexpr SkRect SK_WARN_UNUSED_RESULT MakeLTRB(SkScalar l, SkScalar t, SkScalar r, + SkScalar b) { + return SkRect {l, t, r, b}; } static SkRect SK_WARN_UNUSED_RESULT MakeXYWH(SkScalar x, SkScalar y, SkScalar w, SkScalar h) { @@ -411,6 +439,10 @@ struct SK_API SkRect { return r; } + static SkRect Make(const SkISize& size) { + return MakeIWH(size.width(), size.height()); + } + static SkRect SK_WARN_UNUSED_RESULT Make(const SkIRect& irect) { SkRect r; r.set(SkIntToScalar(irect.fLeft), @@ -432,8 +464,7 @@ struct SK_API SkRect { /** * Returns true iff all values in the rect are finite. If any are - * infinite or NaN (or SK_FixedNaN when SkScalar is fixed) then this - * returns false. + * infinite or NaN then this returns false. */ bool isFinite() const { float accum = 0; @@ -443,11 +474,11 @@ struct SK_API SkRect { accum *= fBottom; // accum is either NaN or it is finite (zero). - SkASSERT(0 == accum || !(accum == accum)); + SkASSERT(0 == accum || SkScalarIsNaN(accum)); // value==value will be true iff value is not NaN // TODO: is it faster to say !accum or accum==accum? - return accum == accum; + return !SkScalarIsNaN(accum); } SkScalar x() const { return fLeft; } @@ -476,7 +507,7 @@ struct SK_API SkRect { /** Set this rectangle to the empty rectangle (0,0,0,0) */ - void setEmpty() { memset(this, 0, sizeof(*this)); } + void setEmpty() { *this = MakeEmpty(); } void set(const SkIRect& src) { fLeft = SkIntToScalar(src.fLeft); @@ -577,6 +608,27 @@ struct SK_API SkRect { fRight = fBottom = SK_ScalarMin; } + /** + * Return a new Rect, built as an offset of this rect. + */ + SkRect makeOffset(SkScalar dx, SkScalar dy) const { + return MakeLTRB(fLeft + dx, fTop + dy, fRight + dx, fBottom + dy); + } + + /** + * Return a new Rect, built as an inset of this rect. + */ + SkRect makeInset(SkScalar dx, SkScalar dy) const { + return MakeLTRB(fLeft + dx, fTop + dy, fRight - dx, fBottom - dy); + } + + /** + * Return a new Rect, built as an outset of this rect. + */ + SkRect makeOutset(SkScalar dx, SkScalar dy) const { + return MakeLTRB(fLeft - dx, fTop - dy, fRight + dx, fBottom + dy); + } + /** Offset set the rectangle by adding dx to its left and right, and adding dy to its top and bottom. */ @@ -624,42 +676,54 @@ struct SK_API SkRect { intersection, otherwise return false and do not change this rectangle. If either rectangle is empty, do nothing and return false. */ - bool intersect(const SkRect& r); - bool intersect2(const SkRect& r); + bool SK_WARN_UNUSED_RESULT intersect(const SkRect& r); /** If this rectangle intersects the rectangle specified by left, top, right, bottom, return true and set this rectangle to that intersection, otherwise return false and do not change this rectangle. If either rectangle is empty, do nothing and return false. */ - bool intersect(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom); + bool SK_WARN_UNUSED_RESULT intersect(SkScalar left, SkScalar top, + SkScalar right, SkScalar bottom); + /** + * If rectangles a and b intersect, return true and set this rectangle to + * that intersection, otherwise return false and do not change this + * rectangle. If either rectangle is empty, do nothing and return false. + */ + bool SK_WARN_UNUSED_RESULT intersect(const SkRect& a, const SkRect& b); + + +private: + static bool Intersects(SkScalar al, SkScalar at, SkScalar ar, SkScalar ab, + SkScalar bl, SkScalar bt, SkScalar br, SkScalar bb) { + SkScalar L = SkMaxScalar(al, bl); + SkScalar R = SkMinScalar(ar, br); + SkScalar T = SkMaxScalar(at, bt); + SkScalar B = SkMinScalar(ab, bb); + return L < R && T < B; + } + +public: /** * Return true if this rectangle is not empty, and the specified sides of * a rectangle are not empty, and they intersect. */ bool intersects(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom) const { - return // first check that both are not empty - left < right && top < bottom && - fLeft < fRight && fTop < fBottom && - // now check for intersection - fLeft < right && left < fRight && - fTop < bottom && top < fBottom; + return Intersects(fLeft, fTop, fRight, fBottom, left, top, right, bottom); } - /** If rectangles a and b intersect, return true and set this rectangle to - * that intersection, otherwise return false and do not change this - * rectangle. If either rectangle is empty, do nothing and return false. - */ - bool intersect(const SkRect& a, const SkRect& b); + bool intersects(const SkRect& r) const { + return Intersects(fLeft, fTop, fRight, fBottom, + r.fLeft, r.fTop, r.fRight, r.fBottom); + } /** * Return true if rectangles a and b are not empty and intersect. */ static bool Intersects(const SkRect& a, const SkRect& b) { - return !a.isEmpty() && !b.isEmpty() && - a.fLeft < b.fRight && b.fLeft < a.fRight && - a.fTop < b.fBottom && b.fTop < a.fBottom; + return Intersects(a.fLeft, a.fTop, a.fRight, a.fBottom, + b.fLeft, b.fTop, b.fRight, b.fBottom); } /** @@ -676,8 +740,27 @@ struct SK_API SkRect { void join(const SkRect& r) { this->join(r.fLeft, r.fTop, r.fRight, r.fBottom); } - // alias for join() - void growToInclude(const SkRect& r) { this->join(r); } + + void joinNonEmptyArg(const SkRect& r) { + SkASSERT(!r.isEmpty()); + // if we are empty, just assign + if (fLeft >= fRight || fTop >= fBottom) { + *this = r; + } else { + this->joinPossiblyEmptyRect(r); + } + } + + /** + * Joins the rectangle with another without checking if either are empty (may produce unexpected + * results if either rect is inverted). + */ + void joinPossiblyEmptyRect(const SkRect& r) { + fLeft = SkMinScalar(fLeft, r.left()); + fTop = SkMinScalar(fTop, r.top()); + fRight = SkMaxScalar(fRight, r.right()); + fBottom = SkMaxScalar(fBottom, r.bottom()); + } /** * Grow the rect to include the specified (x,y). After this call, the @@ -721,6 +804,16 @@ struct SK_API SkRect { fRight >= r.fRight && fBottom >= r.fBottom; } + /** + * Returns true if the specified rectangle r is inside or equal to this rectangle. + */ + bool contains(const SkIRect& r) const { + // todo: can we eliminate the this->isEmpty check? + return !r.isEmpty() && !this->isEmpty() && + fLeft <= SkIntToScalar(r.fLeft) && fTop <= SkIntToScalar(r.fTop) && + fRight >= SkIntToScalar(r.fRight) && fBottom >= SkIntToScalar(r.fBottom); + } + /** * Set the dst rectangle by rounding this rectangle's coordinates to their * nearest integer values using SkScalarRoundToInt. @@ -742,15 +835,16 @@ struct SK_API SkRect { } /** - * Expand this rectangle by rounding its coordinates "out", choosing the - * floor of top and left, and the ceil of right and bottom. If this rect - * is already on integer coordinates, then it will be unchanged. + * Set the dst rectangle by rounding "out" this rectangle, choosing the + * SkScalarFloorToScalar of top and left, and the SkScalarCeilToScalar of right and bottom. + * + * It is safe for this == dst */ - void roundOut() { - this->set(SkScalarFloorToScalar(fLeft), - SkScalarFloorToScalar(fTop), - SkScalarCeilToScalar(fRight), - SkScalarCeilToScalar(fBottom)); + void roundOut(SkRect* dst) const { + dst->set(SkScalarFloorToScalar(fLeft), + SkScalarFloorToScalar(fTop), + SkScalarCeilToScalar(fRight), + SkScalarCeilToScalar(fBottom)); } /** @@ -765,28 +859,50 @@ struct SK_API SkRect { SkScalarFloorToInt(fRight), SkScalarFloorToInt(fBottom)); } - /** - * Return a new SkIRect which is contains the rounded coordinates of this - * rect using SkScalarRoundToInt. - */ + //! Returns the result of calling round(&dst) SkIRect round() const { SkIRect ir; this->round(&ir); return ir; } - + + //! Returns the result of calling roundOut(&dst) + SkIRect roundOut() const { + SkIRect ir; + this->roundOut(&ir); + return ir; + } + /** * Swap top/bottom or left/right if there are flipped (i.e. if width() * or height() would have returned a negative value.) This should be called * if the edges are computed separately, and may have crossed over each * other. When this returns, left <= right && top <= bottom */ - void sort(); + void sort() { + if (fLeft > fRight) { + SkTSwap(fLeft, fRight); + } + + if (fTop > fBottom) { + SkTSwap(fTop, fBottom); + } + } /** * cast-safe way to treat the rect as an array of (4) SkScalars. */ const SkScalar* asScalars() const { return &fLeft; } + + void dump(bool asHex) const; + void dump() const { this->dump(false); } + void dumpHex() const { this->dump(true); } }; +inline bool SkIRect::contains(const SkRect& r) const { + return !r.isEmpty() && !this->isEmpty() && // check for empties + (SkScalar)fLeft <= r.fLeft && (SkScalar)fTop <= r.fTop && + (SkScalar)fRight >= r.fRight && (SkScalar)fBottom >= r.fBottom; +} + #endif diff --git a/libskia/include/core/SkRefCnt.h b/libskia/include/core/SkRefCnt.h index 28591920..53523b41 100644 --- a/libskia/include/core/SkRefCnt.h +++ b/libskia/include/core/SkRefCnt.h @@ -1,4 +1,3 @@ - /* * Copyright 2006 The Android Open Source Project * @@ -6,13 +5,18 @@ * found in the LICENSE file. */ - #ifndef SkRefCnt_DEFINED #define SkRefCnt_DEFINED -#include "SkThread.h" -#include "SkInstCnt.h" -#include "SkTemplates.h" +#include "../private/SkTLogic.h" +#include "SkTypes.h" +#include +#include +#include +#include +#include + +#define SK_SUPPORT_TRANSITION_TO_SP_INTERFACES /** \class SkRefCntBase @@ -24,10 +28,8 @@ destructor to be called explicitly (or via the object going out of scope on the stack or calling delete) if getRefCnt() > 1. */ -class SK_API SkRefCntBase : public SkNoncopyable { +class SK_API SkRefCntBase : SkNoncopyable { public: - SK_DECLARE_INST_COUNT_ROOT(SkRefCntBase) - /** Default construct, initializing the reference count to 1. */ SkRefCntBase() : fRefCnt(1) {} @@ -36,32 +38,42 @@ class SK_API SkRefCntBase : public SkNoncopyable { */ virtual ~SkRefCntBase() { #ifdef SK_DEBUG - SkASSERT(fRefCnt == 1); - fRefCnt = 0; // illegal value, to catch us if we reuse after delete + SkASSERTF(getRefCnt() == 1, "fRefCnt was %d", getRefCnt()); + // illegal value, to catch us if we reuse after delete + fRefCnt.store(0, std::memory_order_relaxed); #endif } +#ifdef SK_DEBUG /** Return the reference count. Use only for debugging. */ - int32_t getRefCnt() const { return fRefCnt; } + int32_t getRefCnt() const { + return fRefCnt.load(std::memory_order_relaxed); + } - /** Returns true if the caller is the only owner. + void validate() const { + SkASSERT(getRefCnt() > 0); + } +#endif + + /** May return true if the caller is the only owner. * Ensures that all previous owner's actions are complete. */ bool unique() const { - bool const unique = (1 == fRefCnt); - if (unique) { - // Acquire barrier (L/SL), if not provided by load of fRefCnt. - // Prevents user's 'unique' code from happening before decrements. - //TODO: issue the barrier. + if (1 == fRefCnt.load(std::memory_order_acquire)) { + // The acquire barrier is only really needed if we return true. It + // prevents code conditioned on the result of unique() from running + // until previous owners are all totally done calling unref(). + return true; } - return unique; + return false; } /** Increment the reference count. Must be balanced by a call to unref(). */ void ref() const { - SkASSERT(fRefCnt > 0); - sk_atomic_inc(&fRefCnt); // No barrier required. + SkASSERT(getRefCnt() > 0); + // No barrier required. + (void)fRefCnt.fetch_add(+1, std::memory_order_relaxed); } /** Decrement the reference count. If the reference count is 1 before the @@ -69,34 +81,24 @@ class SK_API SkRefCntBase : public SkNoncopyable { the object needs to have been allocated via new, and not on the stack. */ void unref() const { - SkASSERT(fRefCnt > 0); - // Release barrier (SL/S), if not provided below. - if (sk_atomic_dec(&fRefCnt) == 1) { - // Acquire barrier (L/SL), if not provided above. - // Prevents code in dispose from happening before the decrement. - sk_membar_acquire__after_atomic_dec(); - internal_dispose(); + SkASSERT(getRefCnt() > 0); + // A release here acts in place of all releases we "should" have been doing in ref(). + if (1 == fRefCnt.fetch_add(-1, std::memory_order_acq_rel)) { + // Like unique(), the acquire is only needed on success, to make sure + // code in internal_dispose() doesn't happen before the decrement. + this->internal_dispose(); } } -#ifdef SK_DEBUG - void validate() const { - SkASSERT(fRefCnt > 0); - } -#endif - protected: /** * Allow subclasses to call this if they've overridden internal_dispose - * so they can reset fRefCnt before the destructor is called. Should only - * be called right before calling through to inherited internal_dispose() - * or before calling the destructor. + * so they can reset fRefCnt before the destructor is called or if they + * choose not to call the destructor (e.g. using a free list). */ void internal_dispose_restore_refcnt_to_1() const { -#ifdef SK_DEBUG - SkASSERT(0 == fRefCnt); - fRefCnt = 1; -#endif + SkASSERT(0 == getRefCnt()); + fRefCnt.store(1, std::memory_order_relaxed); } private: @@ -105,15 +107,14 @@ class SK_API SkRefCntBase : public SkNoncopyable { */ virtual void internal_dispose() const { this->internal_dispose_restore_refcnt_to_1(); - SkDELETE(this); + delete this; } // The following friends are those which override internal_dispose() // and conditionally call SkRefCnt::internal_dispose(). - friend class GrTexture; friend class SkWeakRefCnt; - mutable int32_t fRefCnt; + mutable std::atomic fRefCnt; typedef SkNoncopyable INHERITED; }; @@ -123,7 +124,13 @@ class SK_API SkRefCntBase : public SkNoncopyable { // This SkRefCnt should normally derive from SkRefCntBase. #include SK_REF_CNT_MIXIN_INCLUDE #else -class SK_API SkRefCnt : public SkRefCntBase { }; +class SK_API SkRefCnt : public SkRefCntBase { + // "#include SK_REF_CNT_MIXIN_INCLUDE" doesn't work with this build system. + #if defined(GOOGLE3) + public: + void deref() const { this->unref(); } + #endif +}; #endif /////////////////////////////////////////////////////////////////////////////// @@ -140,7 +147,7 @@ class SK_API SkRefCnt : public SkRefCntBase { }; } while (0) -/** Call obj->ref() and return obj. The obj must not be NULL. +/** Call obj->ref() and return obj. The obj must not be nullptr. */ template static inline T* SkRef(T* obj) { SkASSERT(obj); @@ -166,124 +173,260 @@ template static inline void SkSafeUnref(T* obj) { } template static inline void SkSafeSetNull(T*& obj) { - if (NULL != obj) { + if (obj) { obj->unref(); - obj = NULL; + obj = nullptr; } } /////////////////////////////////////////////////////////////////////////////// +// This is a variant of SkRefCnt that's Not Virtual, so weighs 4 bytes instead of 8 or 16. +// There's only benefit to using this if the deriving class does not otherwise need a vtable. +template +class SkNVRefCnt : SkNoncopyable { +public: + SkNVRefCnt() : fRefCnt(1) {} + ~SkNVRefCnt() { SkASSERTF(1 == getRefCnt(), "NVRefCnt was %d", getRefCnt()); } + + // Implementation is pretty much the same as SkRefCntBase. All required barriers are the same: + // - unique() needs acquire when it returns true, and no barrier if it returns false; + // - ref() doesn't need any barrier; + // - unref() needs a release barrier, and an acquire if it's going to call delete. + + bool unique() const { return 1 == fRefCnt.load(std::memory_order_acquire); } + void ref() const { (void)fRefCnt.fetch_add(+1, std::memory_order_relaxed); } + void unref() const { + if (1 == fRefCnt.fetch_add(-1, std::memory_order_acq_rel)) { + // restore the 1 for our destructor's assert + SkDEBUGCODE(fRefCnt.store(1, std::memory_order_relaxed)); + delete (const Derived*)this; + } + } + void deref() const { this->unref(); } + +private: + mutable std::atomic fRefCnt; + int32_t getRefCnt() const { + return fRefCnt.load(std::memory_order_relaxed); + } +}; + +/////////////////////////////////////////////////////////////////////////////////////////////////// + /** - * Utility class that simply unref's its argument in the destructor. + * Shared pointer class to wrap classes that support a ref()/unref() interface. + * + * This can be used for classes inheriting from SkRefCnt, but it also works for other + * classes that match the interface, but have different internal choices: e.g. the hosted class + * may have its ref/unref be thread-safe, but that is not assumed/imposed by sk_sp. */ -template class SkAutoTUnref : SkNoncopyable { +template class sk_sp { + /** Supports safe bool idiom. Obsolete with explicit operator bool. */ + using unspecified_bool_type = T* sk_sp::*; public: - explicit SkAutoTUnref(T* obj = NULL) : fObj(obj) {} - ~SkAutoTUnref() { SkSafeUnref(fObj); } + using element_type = T; - T* get() const { return fObj; } + constexpr sk_sp() : fPtr(nullptr) {} + constexpr sk_sp(std::nullptr_t) : fPtr(nullptr) {} - T* reset(T* obj) { - SkSafeUnref(fObj); - fObj = obj; - return obj; - } + /** + * Shares the underlying object by calling ref(), so that both the argument and the newly + * created sk_sp both have a reference to it. + */ + sk_sp(const sk_sp& that) : fPtr(SkSafeRef(that.get())) {} + template ::value>> + sk_sp(const sk_sp& that) : fPtr(SkSafeRef(that.get())) {} - void swap(SkAutoTUnref* other) { - T* tmp = fObj; - fObj = other->fObj; - other->fObj = tmp; - } + /** + * Move the underlying object from the argument to the newly created sk_sp. Afterwards only + * the new sk_sp will have a reference to the object, and the argument will point to null. + * No call to ref() or unref() will be made. + */ + sk_sp(sk_sp&& that) : fPtr(that.release()) {} + template ::value>> + sk_sp(sk_sp&& that) : fPtr(that.release()) {} /** - * Return the hosted object (which may be null), transferring ownership. - * The reference count is not modified, and the internal ptr is set to NULL - * so unref() will not be called in our destructor. A subsequent call to - * detach() will do nothing and return null. + * Adopt the bare pointer into the newly created sk_sp. + * No call to ref() or unref() will be made. */ - T* detach() { - T* obj = fObj; - fObj = NULL; - return obj; - } + explicit sk_sp(T* obj) : fPtr(obj) {} /** - * BlockRef is a type which inherits from B, cannot be created, - * cannot be deleted, and makes ref and unref private. + * Calls unref() on the underlying object pointer. */ - template class BlockRef : public B { - private: - BlockRef(); - ~BlockRef(); - void ref() const; - void unref() const; - }; + ~sk_sp() { + SkSafeUnref(fPtr); + SkDEBUGCODE(fPtr = nullptr); + } - /** If T is const, the type returned from operator-> will also be const. */ - typedef typename SkTConstType, SkTIsConst::value>::type BlockRefType; + sk_sp& operator=(std::nullptr_t) { this->reset(); return *this; } /** - * SkAutoTUnref assumes ownership of the ref. As a result, it is an error - * for the user to ref or unref through SkAutoTUnref. Therefore - * SkAutoTUnref::operator-> returns BlockRef*. This prevents use of - * skAutoTUnrefInstance->ref() and skAutoTUnrefInstance->unref(). + * Shares the underlying object referenced by the argument by calling ref() on it. If this + * sk_sp previously had a reference to an object (i.e. not null) it will call unref() on that + * object. */ - BlockRefType *operator->() const { - return static_cast(fObj); + sk_sp& operator=(const sk_sp& that) { + this->reset(SkSafeRef(that.get())); + return *this; + } + template ::value>> + sk_sp& operator=(const sk_sp& that) { + this->reset(SkSafeRef(that.get())); + return *this; } - operator T*() { return fObj; } -private: - T* fObj; -}; -// Can't use the #define trick below to guard a bare SkAutoTUnref(...) because it's templated. :( + /** + * Move the underlying object from the argument to the sk_sp. If the sk_sp previously held + * a reference to another object, unref() will be called on that object. No call to ref() + * will be made. + */ + sk_sp& operator=(sk_sp&& that) { + this->reset(that.release()); + return *this; + } + template ::value>> + sk_sp& operator=(sk_sp&& that) { + this->reset(that.release()); + return *this; + } -class SkAutoUnref : public SkAutoTUnref { -public: - SkAutoUnref(SkRefCnt* obj) : SkAutoTUnref(obj) {} -}; -#define SkAutoUnref(...) SK_REQUIRE_LOCAL_VAR(SkAutoUnref) + T& operator*() const { + SkASSERT(this->get() != nullptr); + return *this->get(); + } -class SkAutoRef : SkNoncopyable { -public: - SkAutoRef(SkRefCnt* obj) : fObj(obj) { SkSafeRef(obj); } - ~SkAutoRef() { SkSafeUnref(fObj); } -private: - SkRefCnt* fObj; -}; -#define SkAutoRef(...) SK_REQUIRE_LOCAL_VAR(SkAutoRef) + // MSVC 2013 does not work correctly with explicit operator bool. + // https://chromium-cpp.appspot.com/#core-blacklist + // When explicit operator bool can be used, remove operator! and operator unspecified_bool_type. + //explicit operator bool() const { return this->get() != nullptr; } + operator unspecified_bool_type() const { return this->get() ? &sk_sp::fPtr : nullptr; } + bool operator!() const { return this->get() == nullptr; } -/** Wrapper class for SkRefCnt pointers. This manages ref/unref of a pointer to - a SkRefCnt (or subclass) object. - */ -template class SkRefPtr { -public: - SkRefPtr() : fObj(NULL) {} - SkRefPtr(T* obj) : fObj(obj) { SkSafeRef(fObj); } - SkRefPtr(const SkRefPtr& o) : fObj(o.fObj) { SkSafeRef(fObj); } - ~SkRefPtr() { SkSafeUnref(fObj); } + T* get() const { return fPtr; } + T* operator->() const { return fPtr; } - SkRefPtr& operator=(const SkRefPtr& rp) { - SkRefCnt_SafeAssign(fObj, rp.fObj); - return *this; - } - SkRefPtr& operator=(T* obj) { - SkRefCnt_SafeAssign(fObj, obj); - return *this; + /** + * Adopt the new bare pointer, and call unref() on any previously held object (if not null). + * No call to ref() will be made. + */ + void reset(T* ptr = nullptr) { + // Calling fPtr->unref() may call this->~() or this->reset(T*). + // http://wg21.cmeerw.net/lwg/issue998 + // http://wg21.cmeerw.net/lwg/issue2262 + T* oldPtr = fPtr; + fPtr = ptr; + SkSafeUnref(oldPtr); } - T* get() const { return fObj; } - T& operator*() const { return *fObj; } - T* operator->() const { return fObj; } + /** + * Return the bare pointer, and set the internal object pointer to nullptr. + * The caller must assume ownership of the object, and manage its reference count directly. + * No call to unref() will be made. + */ + T* SK_WARN_UNUSED_RESULT release() { + T* ptr = fPtr; + fPtr = nullptr; + return ptr; + } - typedef T* SkRefPtr::*unspecified_bool_type; - operator unspecified_bool_type() const { - return fObj ? &SkRefPtr::fObj : NULL; + void swap(sk_sp& that) /*noexcept*/ { + using std::swap; + swap(fPtr, that.fPtr); } private: - T* fObj; + T* fPtr; }; +template inline void swap(sk_sp& a, sk_sp& b) /*noexcept*/ { + a.swap(b); +} + +template inline bool operator==(const sk_sp& a, const sk_sp& b) { + return a.get() == b.get(); +} +template inline bool operator==(const sk_sp& a, std::nullptr_t) /*noexcept*/ { + return !a; +} +template inline bool operator==(std::nullptr_t, const sk_sp& b) /*noexcept*/ { + return !b; +} + +template inline bool operator!=(const sk_sp& a, const sk_sp& b) { + return a.get() != b.get(); +} +template inline bool operator!=(const sk_sp& a, std::nullptr_t) /*noexcept*/ { + return static_cast(a); +} +template inline bool operator!=(std::nullptr_t, const sk_sp& b) /*noexcept*/ { + return static_cast(b); +} + +template inline bool operator<(const sk_sp& a, const sk_sp& b) { + // Provide defined total order on sk_sp. + // http://wg21.cmeerw.net/lwg/issue1297 + // http://wg21.cmeerw.net/lwg/issue1401 . + return std::less>()(a.get(), b.get()); +} +template inline bool operator<(const sk_sp& a, std::nullptr_t) { + return std::less()(a.get(), nullptr); +} +template inline bool operator<(std::nullptr_t, const sk_sp& b) { + return std::less()(nullptr, b.get()); +} + +template inline bool operator<=(const sk_sp& a, const sk_sp& b) { + return !(b < a); +} +template inline bool operator<=(const sk_sp& a, std::nullptr_t) { + return !(nullptr < a); +} +template inline bool operator<=(std::nullptr_t, const sk_sp& b) { + return !(b < nullptr); +} + +template inline bool operator>(const sk_sp& a, const sk_sp& b) { + return b < a; +} +template inline bool operator>(const sk_sp& a, std::nullptr_t) { + return nullptr < a; +} +template inline bool operator>(std::nullptr_t, const sk_sp& b) { + return b < nullptr; +} + +template inline bool operator>=(const sk_sp& a, const sk_sp& b) { + return !(a < b); +} +template inline bool operator>=(const sk_sp& a, std::nullptr_t) { + return !(a < nullptr); +} +template inline bool operator>=(std::nullptr_t, const sk_sp& b) { + return !(nullptr < b); +} + +template +sk_sp sk_make_sp(Args&&... args) { + return sk_sp(new T(std::forward(args)...)); +} + +#ifdef SK_SUPPORT_TRANSITION_TO_SP_INTERFACES + +/* + * Returns a sk_sp wrapping the provided ptr AND calls ref on it (if not null). + * + * This is different than the semantics of the constructor for sk_sp, which just wraps the ptr, + * effectively "adopting" it. + * + * This function may be helpful while we convert callers from ptr-based to sk_sp-based parameters. + */ +template sk_sp sk_ref_sp(T* obj) { + return sk_sp(SkSafeRef(obj)); +} + +#endif + #endif diff --git a/libskia/include/core/SkRegion.h b/libskia/include/core/SkRegion.h index c9aa8daf..a0f0e4ad 100644 --- a/libskia/include/core/SkRegion.h +++ b/libskia/include/core/SkRegion.h @@ -59,7 +59,6 @@ class SK_API SkRegion { * resulting region is non-empty. */ bool set(const SkRegion& src) { - SkASSERT(&src); *this = src; return !this->isEmpty(); } @@ -244,15 +243,27 @@ class SK_API SkRegion { kXOR_Op, //!< exclusive-or the two regions /** subtract the first region from the op region */ kReverseDifference_Op, - kReplace_Op //!< replace the dst region with the op region + kReplace_Op, //!< replace the dst region with the op region + + kLastOp = kReplace_Op }; + static const int kOpCnt = kLastOp + 1; + /** * Set this region to the result of applying the Op to this region and the * specified rectangle: this = (this op rect). * Return true if the resulting region is non-empty. */ - bool op(const SkIRect& rect, Op op) { return this->op(*this, rect, op); } + bool op(const SkIRect& rect, Op op) { + if (this->isRect() && kIntersect_Op == op) { + if (!fBounds.intersect(rect)) { + return this->setEmpty(); + } + return true; + } + return this->op(*this, rect, op); + } /** * Set this region to the result of applying the Op to this region and the diff --git a/libskia/include/core/SkScalar.h b/libskia/include/core/SkScalar.h index 70509e49..922840fd 100644 --- a/libskia/include/core/SkScalar.h +++ b/libskia/include/core/SkScalar.h @@ -8,162 +8,197 @@ #ifndef SkScalar_DEFINED #define SkScalar_DEFINED -#include "SkFixed.h" -#include "SkFloatingPoint.h" +#include "../private/SkFloatingPoint.h" -//#define SK_SUPPORT_DEPRECATED_SCALARROUND +// TODO: move this sort of check into SkPostConfig.h +#define SK_SCALAR_IS_DOUBLE 0 +#undef SK_SCALAR_IS_FLOAT +#define SK_SCALAR_IS_FLOAT 1 -typedef float SkScalar; -/** SK_Scalar1 is defined to be 1.0 represented as an SkScalar -*/ -#define SK_Scalar1 (1.0f) -/** SK_Scalar1 is defined to be 1/2 represented as an SkScalar -*/ -#define SK_ScalarHalf (0.5f) -/** SK_ScalarInfinity is defined to be infinity as an SkScalar -*/ -#define SK_ScalarInfinity SK_FloatInfinity -/** SK_ScalarNegativeInfinity is defined to be negative infinity as an SkScalar -*/ -#define SK_ScalarNegativeInfinity SK_FloatNegativeInfinity -/** SK_ScalarMax is defined to be the largest value representable as an SkScalar -*/ -#define SK_ScalarMax (3.402823466e+38f) -/** SK_ScalarMin is defined to be the smallest value representable as an SkScalar -*/ +#if SK_SCALAR_IS_FLOAT + +typedef float SkScalar; + +#define SK_Scalar1 1.0f +#define SK_ScalarHalf 0.5f +#define SK_ScalarSqrt2 1.41421356f +#define SK_ScalarPI 3.14159265f +#define SK_ScalarTanPIOver8 0.414213562f +#define SK_ScalarRoot2Over2 0.707106781f +#define SK_ScalarMax 3.402823466e+38f +#define SK_ScalarInfinity SK_FloatInfinity +#define SK_ScalarNegativeInfinity SK_FloatNegativeInfinity +#define SK_ScalarNaN SK_FloatNaN + +#define SkScalarFloorToScalar(x) sk_float_floor(x) +#define SkScalarCeilToScalar(x) sk_float_ceil(x) +#define SkScalarRoundToScalar(x) sk_float_floor((x) + 0.5f) +#define SkScalarTruncToScalar(x) sk_float_trunc(x) + +#define SkScalarFloorToInt(x) sk_float_floor2int(x) +#define SkScalarCeilToInt(x) sk_float_ceil2int(x) +#define SkScalarRoundToInt(x) sk_float_round2int(x) + +#define SkScalarAbs(x) sk_float_abs(x) +#define SkScalarCopySign(x, y) sk_float_copysign(x, y) +#define SkScalarMod(x, y) sk_float_mod(x,y) +#define SkScalarSqrt(x) sk_float_sqrt(x) +#define SkScalarPow(b, e) sk_float_pow(b, e) + +#define SkScalarSin(radians) (float)sk_float_sin(radians) +#define SkScalarCos(radians) (float)sk_float_cos(radians) +#define SkScalarTan(radians) (float)sk_float_tan(radians) +#define SkScalarASin(val) (float)sk_float_asin(val) +#define SkScalarACos(val) (float)sk_float_acos(val) +#define SkScalarATan2(y, x) (float)sk_float_atan2(y,x) +#define SkScalarExp(x) (float)sk_float_exp(x) +#define SkScalarLog(x) (float)sk_float_log(x) +#define SkScalarLog2(x) (float)sk_float_log2(x) + +#else // SK_SCALAR_IS_DOUBLE + +typedef double SkScalar; + +#define SK_Scalar1 1.0 +#define SK_ScalarHalf 0.5 +#define SK_ScalarSqrt2 1.414213562373095 +#define SK_ScalarPI 3.141592653589793 +#define SK_ScalarTanPIOver8 0.4142135623731 +#define SK_ScalarRoot2Over2 0.70710678118655 +#define SK_ScalarMax 1.7976931348623157+308 +#define SK_ScalarInfinity SK_DoubleInfinity +#define SK_ScalarNegativeInfinity SK_DoubleNegativeInfinity +#define SK_ScalarNaN SK_DoubleNaN + +#define SkScalarFloorToScalar(x) floor(x) +#define SkScalarCeilToScalar(x) ceil(x) +#define SkScalarRoundToScalar(x) floor((x) + 0.5) +#define SkScalarTruncToScalar(x) trunc(x) + +#define SkScalarFloorToInt(x) (int)floor(x) +#define SkScalarCeilToInt(x) (int)ceil(x) +#define SkScalarRoundToInt(x) (int)floor((x) + 0.5) + +#define SkScalarAbs(x) abs(x) +#define SkScalarCopySign(x, y) copysign(x, y) +#define SkScalarMod(x, y) fmod(x,y) +#define SkScalarSqrt(x) sqrt(x) +#define SkScalarPow(b, e) pow(b, e) + +#define SkScalarSin(radians) sin(radians) +#define SkScalarCos(radians) cos(radians) +#define SkScalarTan(radians) tan(radians) +#define SkScalarASin(val) asin(val) +#define SkScalarACos(val) acos(val) +#define SkScalarATan2(y, x) atan2(y,x) +#define SkScalarExp(x) exp(x) +#define SkScalarLog(x) log(x) +#define SkScalarLog2(x) log2(x) + +#endif + +////////////////////////////////////////////////////////////////////////////////////////////////// + +#define SkIntToScalar(x) static_cast(x) +#define SkIntToFloat(x) static_cast(x) +#define SkScalarTruncToInt(x) static_cast(x) + +#define SkScalarToFloat(x) static_cast(x) +#define SkFloatToScalar(x) static_cast(x) +#define SkScalarToDouble(x) static_cast(x) +#define SkDoubleToScalar(x) static_cast(x) + #define SK_ScalarMin (-SK_ScalarMax) -/** SK_ScalarNaN is defined to be 'Not a Number' as an SkScalar -*/ -#define SK_ScalarNaN SK_FloatNaN -/** SkScalarIsNaN(n) returns true if argument is not a number -*/ -static inline bool SkScalarIsNaN(float x) { return x != x; } -/** Returns true if x is not NaN and not infinite */ -static inline bool SkScalarIsFinite(float x) { +static inline bool SkScalarIsNaN(SkScalar x) { return x != x; } + +/** Returns true if x is not NaN and not infinite + */ +static inline bool SkScalarIsFinite(SkScalar x) { // We rely on the following behavior of infinities and nans // 0 * finite --> 0 // 0 * infinity --> NaN // 0 * NaN --> NaN - float prod = x * 0; + SkScalar prod = x * 0; // At this point, prod will either be NaN or 0 - // Therefore we can return (prod == prod) or (0 == prod). - return prod == prod; + return !SkScalarIsNaN(prod); } -/** SkIntToScalar(n) returns its integer argument as an SkScalar -*/ -#define SkIntToScalar(n) ((float)(n)) -/** SkFixedToScalar(n) returns its SkFixed argument as an SkScalar -*/ -#define SkFixedToScalar(x) SkFixedToFloat(x) -/** SkScalarToFixed(n) returns its SkScalar argument as an SkFixed -*/ -#define SkScalarToFixed(x) SkFloatToFixed(x) - -#define SkScalarToFloat(n) (n) -#ifndef SK_SCALAR_TO_FLOAT_EXCLUDED -#define SkFloatToScalar(n) (n) -#endif - -#define SkScalarToDouble(n) (double)(n) -#define SkDoubleToScalar(n) (float)(n) +static inline bool SkScalarsAreFinite(SkScalar a, SkScalar b) { + SkScalar prod = 0; + prod *= a; + prod *= b; + // At this point, prod will either be NaN or 0 + return !SkScalarIsNaN(prod); +} -/** SkScalarFraction(x) returns the signed fractional part of the argument -*/ -#define SkScalarFraction(x) sk_float_mod(x, 1.0f) +static inline bool SkScalarsAreFinite(const SkScalar array[], int count) { + SkScalar prod = 0; + for (int i = 0; i < count; ++i) { + prod *= array[i]; + } + // At this point, prod will either be NaN or 0 + return !SkScalarIsNaN(prod); +} -#define SkScalarFloorToScalar(x) sk_float_floor(x) -#define SkScalarCeilToScalar(x) sk_float_ceil(x) -#define SkScalarRoundToScalar(x) sk_float_floor((x) + 0.5f) +/** + * Variant of SkScalarRoundToInt, that performs the rounding step (adding 0.5) explicitly using + * double, to avoid possibly losing the low bit(s) of the answer before calling floor(). + * + * This routine will likely be slower than SkScalarRoundToInt(), and should only be used when the + * extra precision is known to be valuable. + * + * In particular, this catches the following case: + * SkScalar x = 0.49999997; + * int ix = SkScalarRoundToInt(x); + * SkASSERT(0 == ix); // <--- fails + * ix = SkDScalarRoundToInt(x); + * SkASSERT(0 == ix); // <--- succeeds + */ +static inline int SkDScalarRoundToInt(SkScalar x) { + double xx = x; + xx += 0.5; + return (int)floor(xx); +} -#define SkScalarFloorToInt(x) sk_float_floor2int(x) -#define SkScalarCeilToInt(x) sk_float_ceil2int(x) -#define SkScalarRoundToInt(x) sk_float_round2int(x) -#define SkScalarTruncToInt(x) static_cast(x) +/** Returns the fractional part of the scalar. */ +static inline SkScalar SkScalarFraction(SkScalar x) { + return x - SkScalarTruncToScalar(x); +} -/** Returns the absolute value of the specified SkScalar -*/ -#define SkScalarAbs(x) sk_float_abs(x) -/** Return x with the sign of y - */ -#define SkScalarCopySign(x, y) sk_float_copysign(x, y) -/** Returns the value pinned between 0 and max inclusive -*/ -inline SkScalar SkScalarClampMax(SkScalar x, SkScalar max) { - return x < 0 ? 0 : x > max ? max : x; +static inline SkScalar SkScalarClampMax(SkScalar x, SkScalar max) { + x = SkTMin(x, max); + x = SkTMax(x, 0); + return x; } -/** Returns the value pinned between min and max inclusive -*/ -inline SkScalar SkScalarPin(SkScalar x, SkScalar min, SkScalar max) { - return x < min ? min : x > max ? max : x; + +static inline SkScalar SkScalarPin(SkScalar x, SkScalar min, SkScalar max) { + return SkTPin(x, min, max); } -/** Returns the specified SkScalar squared (x*x) -*/ -inline SkScalar SkScalarSquare(SkScalar x) { return x * x; } -/** Returns the product of two SkScalars -*/ -#define SkScalarMul(a, b) ((float)(a) * (b)) -/** Returns the product of two SkScalars plus a third SkScalar -*/ -#define SkScalarMulAdd(a, b, c) ((float)(a) * (b) + (c)) -/** Returns the quotient of two SkScalars (a/b) -*/ -#define SkScalarDiv(a, b) ((float)(a) / (b)) -/** Returns the mod of two SkScalars (a mod b) -*/ -#define SkScalarMod(x,y) sk_float_mod(x,y) -/** Returns the product of the first two arguments, divided by the third argument -*/ -#define SkScalarMulDiv(a, b, c) ((float)(a) * (b) / (c)) -/** Returns the multiplicative inverse of the SkScalar (1/x) -*/ + +SkScalar SkScalarSinCos(SkScalar radians, SkScalar* cosValue); + +static inline SkScalar SkScalarSquare(SkScalar x) { return x * x; } + +#define SkScalarMul(a, b) ((SkScalar)(a) * (b)) +#define SkScalarMulAdd(a, b, c) ((SkScalar)(a) * (b) + (c)) +#define SkScalarMulDiv(a, b, c) ((SkScalar)(a) * (b) / (c)) #define SkScalarInvert(x) (SK_Scalar1 / (x)) #define SkScalarFastInvert(x) (SK_Scalar1 / (x)) -/** Returns the square root of the SkScalar -*/ -#define SkScalarSqrt(x) sk_float_sqrt(x) -/** Returns b to the e -*/ -#define SkScalarPow(b, e) sk_float_pow(b, e) -/** Returns the average of two SkScalars (a+b)/2 -*/ -#define SkScalarAve(a, b) (((a) + (b)) * 0.5f) -/** Returns one half of the specified SkScalar -*/ -#define SkScalarHalf(a) ((a) * 0.5f) - -#define SK_ScalarSqrt2 1.41421356f -#define SK_ScalarPI 3.14159265f -#define SK_ScalarTanPIOver8 0.414213562f -#define SK_ScalarRoot2Over2 0.707106781f +#define SkScalarAve(a, b) (((a) + (b)) * SK_ScalarHalf) +#define SkScalarHalf(a) ((a) * SK_ScalarHalf) #define SkDegreesToRadians(degrees) ((degrees) * (SK_ScalarPI / 180)) -float SkScalarSinCos(SkScalar radians, SkScalar* cosValue); -#define SkScalarSin(radians) (float)sk_float_sin(radians) -#define SkScalarCos(radians) (float)sk_float_cos(radians) -#define SkScalarTan(radians) (float)sk_float_tan(radians) -#define SkScalarASin(val) (float)sk_float_asin(val) -#define SkScalarACos(val) (float)sk_float_acos(val) -#define SkScalarATan2(y, x) (float)sk_float_atan2(y,x) -#define SkScalarExp(x) (float)sk_float_exp(x) -#define SkScalarLog(x) (float)sk_float_log(x) - -inline SkScalar SkMaxScalar(SkScalar a, SkScalar b) { return a > b ? a : b; } -inline SkScalar SkMinScalar(SkScalar a, SkScalar b) { return a < b ? a : b; } +#define SkRadiansToDegrees(radians) ((radians) * (180 / SK_ScalarPI)) + +static inline SkScalar SkMaxScalar(SkScalar a, SkScalar b) { return a > b ? a : b; } +static inline SkScalar SkMinScalar(SkScalar a, SkScalar b) { return a < b ? a : b; } static inline bool SkScalarIsInt(SkScalar x) { - return x == (float)(int)x; + return x == (SkScalar)(int)x; } -// DEPRECATED : use ToInt or ToScalar variant -#ifdef SK_SUPPORT_DEPRECATED_SCALARROUND -# define SkScalarFloor(x) SkScalarFloorToInt(x) -# define SkScalarCeil(x) SkScalarCeilToInt(x) -# define SkScalarRound(x) SkScalarRoundToInt(x) -#endif - /** * Returns -1 || 0 || 1 depending on the sign of value: * -1 if x < 0 @@ -182,13 +217,13 @@ static inline SkScalar SkScalarSignAsScalar(SkScalar x) { #define SK_ScalarNearlyZero (SK_Scalar1 / (1 << 12)) static inline bool SkScalarNearlyZero(SkScalar x, - SkScalar tolerance = SK_ScalarNearlyZero) { + SkScalar tolerance = SK_ScalarNearlyZero) { SkASSERT(tolerance >= 0); return SkScalarAbs(x) <= tolerance; } static inline bool SkScalarNearlyEqual(SkScalar x, SkScalar y, - SkScalar tolerance = SK_ScalarNearlyZero) { + SkScalar tolerance = SK_ScalarNearlyZero) { SkASSERT(tolerance >= 0); return SkScalarAbs(x-y) <= tolerance; } @@ -201,7 +236,7 @@ static inline bool SkScalarNearlyEqual(SkScalar x, SkScalar y, */ static inline SkScalar SkScalarInterp(SkScalar A, SkScalar B, SkScalar t) { SkASSERT(t >= 0 && t <= SK_Scalar1); - return A + SkScalarMul(B - A, t); + return A + (B - A) * t; } /** Interpolate along the function described by (keys[length], values[length]) diff --git a/libskia/include/core/SkShader.h b/libskia/include/core/SkShader.h index cdb7a2fd..9e05a388 100644 --- a/libskia/include/core/SkShader.h +++ b/libskia/include/core/SkShader.h @@ -5,19 +5,27 @@ * found in the LICENSE file. */ - #ifndef SkShader_DEFINED #define SkShader_DEFINED #include "SkBitmap.h" +#include "SkFilterQuality.h" #include "SkFlattenable.h" +#include "SkImageInfo.h" #include "SkMask.h" #include "SkMatrix.h" #include "SkPaint.h" +#include "../gpu/GrColor.h" +class SkColorFilter; +class SkColorSpace; +class SkFallbackAlloc; +class SkImage; class SkPath; +class SkPicture; +class SkRasterPipeline; class GrContext; -class GrEffectRef; +class GrFragmentProcessor; /** \class SkShader * @@ -31,32 +39,17 @@ class GrEffectRef; */ class SK_API SkShader : public SkFlattenable { public: - SK_DECLARE_INST_COUNT(SkShader) - - SkShader(); + SkShader(const SkMatrix* localMatrix = NULL); virtual ~SkShader(); - /** - * Returns true if the local matrix is not an identity matrix. - */ - bool hasLocalMatrix() const { return !fLocalMatrix.isIdentity(); } - /** * Returns the local matrix. + * + * FIXME: This can be incorrect for a Shader with its own local matrix + * that is also wrapped via CreateLocalMatrixShader. */ const SkMatrix& getLocalMatrix() const { return fLocalMatrix; } - /** - * Set the shader's local matrix. - * @param localM The shader's new local matrix. - */ - void setLocalMatrix(const SkMatrix& localM) { fLocalMatrix = localM; } - - /** - * Reset the shader's local matrix to identity. - */ - void resetLocalMatrix() { fLocalMatrix.reset(); } - enum TileMode { /** replicate the edge color if the shader draws outside of its * original bounds @@ -75,191 +68,201 @@ class SK_API SkShader : public SkFlattenable { /** only draw within the original domain, return 0 everywhere else */ kDecal_TileMode, #endif + }; - kTileModeCount + enum { + kTileModeCount = kMirror_TileMode + 1 }; // override these in your subclass enum Flags { //!< set if all of the colors will be opaque - kOpaqueAlpha_Flag = 0x01, - - //! set if this shader's shadeSpan16() method can be called - kHasSpan16_Flag = 0x02, - - /** Set this bit if the shader's native data type is instrinsically 16 - bit, meaning that calling the 32bit shadeSpan() entry point will - mean the the impl has to up-sample 16bit data into 32bit. Used as a - a means of clearing a dither request if the it will have no effect - */ - kIntrinsicly16_Flag = 0x04, + kOpaqueAlpha_Flag = 1 << 0, - /** set (after setContext) if the spans only vary in X (const in Y). + /** set if the spans only vary in X (const in Y). e.g. an Nx1 bitmap that is being tiled in Y, or a linear-gradient that varies from left-to-right. This flag specifies this for shadeSpan(). */ - kConstInY32_Flag = 0x08, + kConstInY32_Flag = 1 << 1, - /** same as kConstInY32_Flag, but is set if this is true for shadeSpan16 - which may not always be the case, since shadeSpan16 may be - predithered, which would mean it was not const in Y, even though - the 32bit shadeSpan() would be const. + /** hint for the blitter that 4f is the preferred shading mode. */ - kConstInY16_Flag = 0x10 + kPrefers4f_Flag = 1 << 2, }; - /** - * Called sometimes before drawing with this shader. Return the type of - * alpha your shader will return. The default implementation returns 0. - * Your subclass should override if it can (even sometimes) report a - * non-zero value, since that will enable various blitters to perform - * faster. - */ - virtual uint32_t getFlags() { return 0; } - /** * Returns true if the shader is guaranteed to produce only opaque * colors, subject to the SkPaint using the shader to apply an opaque * alpha value. Subclasses should override this to allow some - * optimizations. isOpaque() can be called at any time, unlike getFlags, - * which only works properly when the context is set. + * optimizations. */ virtual bool isOpaque() const { return false; } /** - * Return the alpha associated with the data returned by shadeSpan16(). If - * kHasSpan16_Flag is not set, this value is meaningless. + * Returns true if the shader is guaranteed to produce only a single color. + * Subclasses can override this to allow loop-hoisting optimization. */ - virtual uint8_t getSpan16Alpha() const { return fPaintAlpha; } + virtual bool isConstant() const { return false; } /** - * Called once before drawing, with the current paint and device matrix. - * Return true if your shader supports these parameters, or false if not. - * If false is returned, nothing will be drawn. If true is returned, then - * a balancing call to endContext() will be made before the next call to - * setContext. - * - * Subclasses should be sure to call their INHERITED::setContext() if they - * override this method. + * ContextRec acts as a parameter bundle for creating Contexts. */ - virtual bool setContext(const SkBitmap& device, const SkPaint& paint, - const SkMatrix& matrix); + struct ContextRec { + enum DstType { + kPMColor_DstType, // clients prefer shading into PMColor dest + kPM4f_DstType, // clients prefer shading into PM4f dest + }; + + ContextRec(const SkPaint& paint, const SkMatrix& matrix, const SkMatrix* localM, + DstType dstType) + : fPaint(&paint) + , fMatrix(&matrix) + , fLocalMatrix(localM) + , fPreferredDstType(dstType) {} + + const SkPaint* fPaint; // the current paint associated with the draw + const SkMatrix* fMatrix; // the current matrix in the canvas + const SkMatrix* fLocalMatrix; // optional local matrix + const DstType fPreferredDstType; // the "natural" client dest type + }; - /** - * Assuming setContext returned true, endContext() will be called when - * the draw using the shader has completed. It is an error for setContext - * to be called twice w/o an intervening call to endContext(). - * - * Subclasses should be sure to call their INHERITED::endContext() if they - * override this method. - */ - virtual void endContext(); + class Context : public ::SkNoncopyable { + public: + Context(const SkShader& shader, const ContextRec&); - SkDEBUGCODE(bool setContextHasBeenCalled() const { return SkToBool(fInSetContext); }) + virtual ~Context(); - /** - * Called for each span of the object being drawn. Your subclass should - * set the appropriate colors (with premultiplied alpha) that correspond - * to the specified device coordinates. - */ - virtual void shadeSpan(int x, int y, SkPMColor[], int count) = 0; + /** + * Called sometimes before drawing with this shader. Return the type of + * alpha your shader will return. The default implementation returns 0. + * Your subclass should override if it can (even sometimes) report a + * non-zero value, since that will enable various blitters to perform + * faster. + */ + virtual uint32_t getFlags() const { return 0; } - typedef void (*ShadeProc)(void* ctx, int x, int y, SkPMColor[], int count); - virtual ShadeProc asAShadeProc(void** ctx); + /** + * Called for each span of the object being drawn. Your subclass should + * set the appropriate colors (with premultiplied alpha) that correspond + * to the specified device coordinates. + */ + virtual void shadeSpan(int x, int y, SkPMColor[], int count) = 0; + + virtual void shadeSpan4f(int x, int y, SkPM4f[], int count); + + struct BlitState; + typedef void (*BlitBW)(BlitState*, + int x, int y, const SkPixmap&, int count); + typedef void (*BlitAA)(BlitState*, + int x, int y, const SkPixmap&, int count, const SkAlpha[]); + + struct BlitState { + // inputs + Context* fCtx; + SkBlendMode fMode; + + // outputs + enum { N = 2 }; + void* fStorage[N]; + BlitBW fBlitBW; + BlitAA fBlitAA; + }; + + // Returns true if one or more of the blitprocs are set in the BlitState + bool chooseBlitProcs(const SkImageInfo& info, BlitState* state) { + state->fBlitBW = nullptr; + state->fBlitAA = nullptr; + if (this->onChooseBlitProcs(info, state)) { + SkASSERT(state->fBlitBW || state->fBlitAA); + return true; + } + return false; + } + + /** + * The const void* ctx is only const because all the implementations are const. + * This can be changed to non-const if a new shade proc needs to change the ctx. + */ + typedef void (*ShadeProc)(const void* ctx, int x, int y, SkPMColor[], int count); + virtual ShadeProc asAShadeProc(void** ctx); + + /** + * Similar to shadeSpan, but only returns the alpha-channel for a span. + * The default implementation calls shadeSpan() and then extracts the alpha + * values from the returned colors. + */ + virtual void shadeSpanAlpha(int x, int y, uint8_t alpha[], int count); + + // Notification from blitter::blitMask in case we need to see the non-alpha channels + virtual void set3DMask(const SkMask*) {} + + protected: + // Reference to shader, so we don't have to dupe information. + const SkShader& fShader; + + enum MatrixClass { + kLinear_MatrixClass, // no perspective + kFixedStepInX_MatrixClass, // fast perspective, need to call fixedStepInX() each + // scanline + kPerspective_MatrixClass // slow perspective, need to mappoints each pixel + }; + static MatrixClass ComputeMatrixClass(const SkMatrix&); + + uint8_t getPaintAlpha() const { return fPaintAlpha; } + const SkMatrix& getTotalInverse() const { return fTotalInverse; } + MatrixClass getInverseClass() const { return (MatrixClass)fTotalInverseClass; } + const SkMatrix& getCTM() const { return fCTM; } + + virtual bool onChooseBlitProcs(const SkImageInfo&, BlitState*) { return false; } + + private: + SkMatrix fCTM; + SkMatrix fTotalInverse; + uint8_t fPaintAlpha; + uint8_t fTotalInverseClass; + + typedef SkNoncopyable INHERITED; + }; /** - * Called only for 16bit devices when getFlags() returns - * kOpaqueAlphaFlag | kHasSpan16_Flag + * Create the actual object that does the shading. + * Size of storage must be >= contextSize. */ - virtual void shadeSpan16(int x, int y, uint16_t[], int count); + Context* createContext(const ContextRec&, void* storage) const; /** - * Similar to shadeSpan, but only returns the alpha-channel for a span. - * The default implementation calls shadeSpan() and then extracts the alpha - * values from the returned colors. + * Return the size of a Context returned by createContext. */ - virtual void shadeSpanAlpha(int x, int y, uint8_t alpha[], int count); + size_t contextSize(const ContextRec&) const; +#ifdef SK_SUPPORT_LEGACY_SHADER_ISABITMAP /** - * Helper function that returns true if this shader's shadeSpan16() method - * can be called. + * Returns true if this shader is just a bitmap, and if not null, returns the bitmap, + * localMatrix, and tilemodes. If this is not a bitmap, returns false and ignores the + * out-parameters. */ - bool canCallShadeSpan16() { - return SkShader::CanCallShadeSpan16(this->getFlags()); + bool isABitmap(SkBitmap* outTexture, SkMatrix* outMatrix, TileMode xy[2]) const { + return this->onIsABitmap(outTexture, outMatrix, xy); } - /** - * Helper to check the flags to know if it is legal to call shadeSpan16() - */ - static bool CanCallShadeSpan16(uint32_t flags) { - return (flags & kHasSpan16_Flag) != 0; + bool isABitmap() const { + return this->isABitmap(nullptr, nullptr, nullptr); } +#endif /** - Gives method bitmap should be read to implement a shader. - Also determines number and interpretation of "extra" parameters returned - by asABitmap + * Iff this shader is backed by a single SkImage, return its ptr (the caller must ref this + * if they want to keep it longer than the lifetime of the shader). If not, return nullptr. */ - enum BitmapType { - kNone_BitmapType, //onIsAImage(localMatrix, xy); + } + + bool isAImage() const { + return this->isAImage(nullptr, nullptr) != nullptr; + } /** * If the shader subclass can be represented as a gradient, asAGradient @@ -283,7 +286,7 @@ class SK_API SkShader : public SkFlattenable { * fPoint[0] and fPoint[1] are the end-points of the gradient * Radial: * fPoint[0] and fRadius[0] are the center and radius - * Radial2: + * Conical: * fPoint[0] and fRadius[0] are the center and radius of the 1st circle * fPoint[1] and fRadius[1] are the center and radius of the 2nd circle * Sweep: @@ -295,7 +298,6 @@ class SK_API SkShader : public SkFlattenable { kColor_GradientType, kLinear_GradientType, kRadial_GradientType, - kRadial2_GradientType, kSweep_GradientType, kConical_GradientType, kLast_GradientType = kConical_GradientType @@ -317,17 +319,117 @@ class SK_API SkShader : public SkFlattenable { virtual GradientType asAGradient(GradientInfo* info) const; /** - * If the shader subclass has a GrEffect implementation, this resturns the effect to install. - * The incoming color to the effect has r=g=b=a all extracted from the SkPaint's alpha. - * The output color should be the computed SkShader premul color modulated by the incoming - * color. The GrContext may be used by the effect to create textures. The GPU device does not - * call setContext. Instead we pass the SkPaint here in case the shader needs paint info. + * If the shader subclass is composed of two shaders, return true, and if rec is not NULL, + * fill it out with info about the shader. + * + * These are bare pointers; the ownership and reference count are unchanged. */ - virtual GrEffectRef* asNewEffect(GrContext* context, const SkPaint& paint) const; + + struct ComposeRec { + const SkShader* fShaderA; + const SkShader* fShaderB; + SkBlendMode fBlendMode; + }; + + virtual bool asACompose(ComposeRec*) const { return false; } + +#if SK_SUPPORT_GPU + struct AsFPArgs { + AsFPArgs() {} + AsFPArgs(GrContext* context, + const SkMatrix* viewMatrix, + const SkMatrix* localMatrix, + SkFilterQuality filterQuality, + SkColorSpace* dstColorSpace, + SkDestinationSurfaceColorMode colorMode) + : fContext(context) + , fViewMatrix(viewMatrix) + , fLocalMatrix(localMatrix) + , fFilterQuality(filterQuality) + , fDstColorSpace(dstColorSpace) + , fColorMode(colorMode) {} + + GrContext* fContext; + const SkMatrix* fViewMatrix; + const SkMatrix* fLocalMatrix; + SkFilterQuality fFilterQuality; + SkColorSpace* fDstColorSpace; + SkDestinationSurfaceColorMode fColorMode; + }; + + /** + * Returns a GrFragmentProcessor that implements the shader for the GPU backend. NULL is + * returned if there is no GPU implementation. + * + * The GPU device does not call SkShader::createContext(), instead we pass the view matrix, + * local matrix, and filter quality directly. + * + * The GrContext may be used by the to create textures that are required by the returned + * processor. + * + * The returned GrFragmentProcessor should expect an unpremultiplied input color and + * produce a premultiplied output. + */ + virtual sk_sp asFragmentProcessor(const AsFPArgs&) const; +#endif + + /** + * If the shader can represent its "average" luminance in a single color, return true and + * if color is not NULL, return that color. If it cannot, return false and ignore the color + * parameter. + * + * Note: if this returns true, the returned color will always be opaque, as only the RGB + * components are used to compute luminance. + */ + bool asLuminanceColor(SkColor*) const; + +#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK + /** + * If the shader is a custom shader which has data the caller might want, call this function + * to get that data. + */ + virtual bool asACustomShader(void** /* customData */) const { return false; } +#endif + + ////////////////////////////////////////////////////////////////////////// + // Methods to create combinations or variants of shaders + + /** + * Return a shader that will apply the specified localMatrix to this shader. + * The specified matrix will be applied before any matrix associated with this shader. + */ + sk_sp makeWithLocalMatrix(const SkMatrix&) const; + + /** + * Create a new shader that produces the same colors as invoking this shader and then applying + * the colorfilter. + */ + sk_sp makeWithColorFilter(sk_sp) const; ////////////////////////////////////////////////////////////////////////// // Factory methods for stock shaders + /** + * Call this to create a new "empty" shader, that will not draw anything. + */ + static sk_sp MakeEmptyShader(); + + /** + * Call this to create a new shader that just draws the specified color. This should always + * draw the same as a paint with this color (and no shader). + */ + static sk_sp MakeColorShader(SkColor); + + /** + * Create a shader that draws the specified color (in the specified colorspace). + * + * This works around the limitation that SkPaint::setColor() only takes byte values, and does + * not support specific colorspaces. + */ + static sk_sp MakeColorShader(const SkColor4f&, sk_sp); + + static sk_sp MakeComposeShader(sk_sp dst, sk_sp src, SkBlendMode); + /** Call this to create a new shader that will draw with the specified bitmap. * * If the bitmap cannot be used (e.g. has no pixels, or its dimensions @@ -342,41 +444,86 @@ class SK_API SkShader : public SkFlattenable { * @param tmy The tiling mode to use when sampling the bitmap in the y-direction. * @return Returns a new shader object. Note: this function never returns null. */ - static SkShader* CreateBitmapShader(const SkBitmap& src, - TileMode tmx, TileMode tmy); + static sk_sp MakeBitmapShader(const SkBitmap& src, TileMode tmx, TileMode tmy, + const SkMatrix* localMatrix = nullptr); - SkDEVCODE(virtual void toString(SkString* str) const;) + // NOTE: You can create an SkImage Shader with SkImage::newShader(). + /** Call this to create a new shader that will draw with the specified picture. + * + * @param src The picture to use inside the shader (if not NULL, its ref count + * is incremented). The SkPicture must not be changed after + * successfully creating a picture shader. + * @param tmx The tiling mode to use when sampling the bitmap in the x-direction. + * @param tmy The tiling mode to use when sampling the bitmap in the y-direction. + * @param tile The tile rectangle in picture coordinates: this represents the subset + * (or superset) of the picture used when building a tile. It is not + * affected by localMatrix and does not imply scaling (only translation + * and cropping). If null, the tile rect is considered equal to the picture + * bounds. + * @return Returns a new shader object. Note: this function never returns null. + */ + static sk_sp MakePictureShader(sk_sp src, TileMode tmx, TileMode tmy, + const SkMatrix* localMatrix, const SkRect* tile); + + /** + * If this shader can be represented by another shader + a localMatrix, return that shader and + * the localMatrix. If not, return nullptr and ignore the localMatrix parameter. + */ + virtual sk_sp makeAsALocalMatrixShader(SkMatrix* localMatrix) const; + + SK_TO_STRING_VIRT() SK_DEFINE_FLATTENABLE_TYPE(SkShader) + SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP() + + bool appendStages(SkRasterPipeline*, SkColorSpace*, SkFallbackAlloc*, + const SkMatrix& ctm, const SkPaint&) const; protected: - enum MatrixClass { - kLinear_MatrixClass, // no perspective - kFixedStepInX_MatrixClass, // fast perspective, need to call fixedStepInX() each scanline - kPerspective_MatrixClass // slow perspective, need to mappoints each pixel - }; - static MatrixClass ComputeMatrixClass(const SkMatrix&); + void flatten(SkWriteBuffer&) const override; + + bool computeTotalInverse(const ContextRec&, SkMatrix* totalInverse) const; + + /** + * Your subclass must also override contextSize() if it overrides onCreateContext(). + * Base class impl returns NULL. + */ + virtual Context* onCreateContext(const ContextRec&, void* storage) const; + + /** + * Override this if your subclass overrides createContext, to return the correct size of + * your subclass' context. + */ + virtual size_t onContextSize(const ContextRec&) const; + + virtual bool onAsLuminanceColor(SkColor*) const { + return false; + } + +#ifdef SK_SUPPORT_LEGACY_SHADER_ISABITMAP + virtual bool onIsABitmap(SkBitmap*, SkMatrix*, TileMode[2]) const { + return false; + } +#endif - // These can be called by your subclass after setContext() has been called - uint8_t getPaintAlpha() const { return fPaintAlpha; } - SkBitmap::Config getDeviceConfig() const { return (SkBitmap::Config)fDeviceConfig; } - const SkMatrix& getTotalInverse() const { return fTotalInverse; } - MatrixClass getInverseClass() const { return (MatrixClass)fTotalInverseClass; } + virtual SkImage* onIsAImage(SkMatrix*, TileMode[2]) const { + return nullptr; + } + + virtual bool onAppendStages(SkRasterPipeline*, SkColorSpace*, SkFallbackAlloc*, + const SkMatrix&, const SkPaint&) const { + return false; + } - SkShader(SkFlattenableReadBuffer& ); - virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE; private: - SkMatrix fLocalMatrix; - SkMatrix fTotalInverse; - uint8_t fPaintAlpha; - uint8_t fDeviceConfig; - uint8_t fTotalInverseClass; - SkDEBUGCODE(SkBool8 fInSetContext;) - - static SkShader* CreateBitmapShader(const SkBitmap& src, - TileMode, TileMode, - void* storage, size_t storageSize); - friend class SkAutoBitmapShaderInstall; + // This is essentially const, but not officially so it can be modified in + // constructors. + SkMatrix fLocalMatrix; + + // So the SkLocalMatrixShader can whack fLocalMatrix in its SkReadBuffer constructor. + friend class SkLocalMatrixShader; + friend class SkBitmapProcLegacyShader; // for computeTotalInverse() + typedef SkFlattenable INHERITED; }; diff --git a/libskia/include/core/SkStream.h b/libskia/include/core/SkStream.h index 50ed691e..9fbd694c 100644 --- a/libskia/include/core/SkStream.h +++ b/libskia/include/core/SkStream.h @@ -8,11 +8,10 @@ #ifndef SkStream_DEFINED #define SkStream_DEFINED +#include "SkData.h" #include "SkRefCnt.h" #include "SkScalar.h" -class SkData; - class SkStream; class SkStreamRewindable; class SkStreamSeekable; @@ -36,16 +35,14 @@ class SkStreamMemory; * no more data (at EOF or hit an error). The caller should *not* call again * in hopes of fulfilling more of the request. */ -class SK_API SkStream : public SkRefCnt { //TODO: remove SkRefCnt +class SK_API SkStream : public SkNoncopyable { public: + virtual ~SkStream() {} + /** - * Attempts to open the specified file, and return a stream to it (using - * mmap if available). On success, the caller must call unref() on the - * returned object. On failure, returns NULL. + * Attempts to open the specified file as a stream, returns nullptr on failure. */ - static SkStreamAsset* NewFromFile(const char path[]); - - SK_DECLARE_INST_COUNT(SkStream) + static std::unique_ptr MakeFromFile(const char path[]); /** Reads or skips size number of bytes. * If buffer == NULL, skip size bytes, return how many were skipped. @@ -63,6 +60,21 @@ class SK_API SkStream : public SkRefCnt { //TODO: remove SkRefCnt return this->read(NULL, size); } + /** + * Attempt to peek at size bytes. + * If this stream supports peeking, copy min(size, peekable bytes) into + * buffer, and return the number of bytes copied. + * If the stream does not support peeking, or cannot peek any bytes, + * return 0 and leave buffer unchanged. + * The stream is guaranteed to be in the same visible state after this + * call, regardless of success or failure. + * @param buffer Must not be NULL, and must be at least size bytes. Destination + * to copy bytes. + * @param size Number of bytes to copy. + * @return The number of bytes peeked/copied. + */ + virtual size_t peek(void* /*buffer*/, size_t /*size*/) const { return 0; } + /** Returns true when all the bytes in the stream have been read. * This may return true early (when there are no more bytes to be read) * or late (after the first unsuccessful read). @@ -81,12 +93,6 @@ class SK_API SkStream : public SkRefCnt { //TODO: remove SkRefCnt SkScalar readScalar(); size_t readPackedUInt(); - /** - * Reconstitute an SkData object that was written to the stream - * using SkWStream::writeData(). - */ - SkData* readData(); - //SkStreamRewindable /** Rewinds to the beginning of the stream. Returns true if the stream is known * to be at the beginning after this call returns. @@ -108,13 +114,13 @@ class SK_API SkStream : public SkRefCnt { //TODO: remove SkRefCnt * If an attempt is made to seek past the end of the stream, the position will be set * to the end of the stream. */ - virtual bool seek(size_t position) { return false; } + virtual bool seek(size_t /*position*/) { return false; } /** Seeks to an relative offset in the stream. If this cannot be done, returns false. * If an attempt is made to move to a position outside the stream, the position will be set * to the closest point within the stream (beginning or end). */ - virtual bool move(long offset) { return false; } + virtual bool move(long /*offset*/) { return false; } /** Duplicates this stream. If this cannot be done, returns NULL. * The returned stream will be positioned the same as this stream. @@ -131,53 +137,48 @@ class SK_API SkStream : public SkRefCnt { //TODO: remove SkRefCnt /** Returns the starting address for the data. If this cannot be done, returns NULL. */ //TODO: replace with virtual const SkData* getData() virtual const void* getMemoryBase() { return NULL; } - -private: - typedef SkRefCnt INHERITED; }; /** SkStreamRewindable is a SkStream for which rewind and duplicate are required. */ class SK_API SkStreamRewindable : public SkStream { public: - virtual bool rewind() SK_OVERRIDE = 0; - virtual SkStreamRewindable* duplicate() const SK_OVERRIDE = 0; + bool rewind() override = 0; + SkStreamRewindable* duplicate() const override = 0; }; /** SkStreamSeekable is a SkStreamRewindable for which position, seek, move, and fork are required. */ class SK_API SkStreamSeekable : public SkStreamRewindable { public: - virtual SkStreamSeekable* duplicate() const SK_OVERRIDE = 0; + SkStreamSeekable* duplicate() const override = 0; - virtual bool hasPosition() const SK_OVERRIDE { return true; } - virtual size_t getPosition() const SK_OVERRIDE = 0; - virtual bool seek(size_t position) SK_OVERRIDE = 0; - virtual bool move(long offset) SK_OVERRIDE = 0; - virtual SkStreamSeekable* fork() const SK_OVERRIDE = 0; + bool hasPosition() const override { return true; } + size_t getPosition() const override = 0; + bool seek(size_t position) override = 0; + bool move(long offset) override = 0; + SkStreamSeekable* fork() const override = 0; }; /** SkStreamAsset is a SkStreamSeekable for which getLength is required. */ class SK_API SkStreamAsset : public SkStreamSeekable { public: - virtual SkStreamAsset* duplicate() const SK_OVERRIDE = 0; - virtual SkStreamAsset* fork() const SK_OVERRIDE = 0; + SkStreamAsset* duplicate() const override = 0; + SkStreamAsset* fork() const override = 0; - virtual bool hasLength() const SK_OVERRIDE { return true; } - virtual size_t getLength() const SK_OVERRIDE = 0; + bool hasLength() const override { return true; } + size_t getLength() const override = 0; }; /** SkStreamMemory is a SkStreamAsset for which getMemoryBase is required. */ class SK_API SkStreamMemory : public SkStreamAsset { public: - virtual SkStreamMemory* duplicate() const SK_OVERRIDE = 0; - virtual SkStreamMemory* fork() const SK_OVERRIDE = 0; + SkStreamMemory* duplicate() const override = 0; + SkStreamMemory* fork() const override = 0; - virtual const void* getMemoryBase() SK_OVERRIDE = 0; + const void* getMemoryBase() override = 0; }; class SK_API SkWStream : SkNoncopyable { public: - SK_DECLARE_INST_COUNT_ROOT(SkWStream) - virtual ~SkWStream(); /** Called to write bytes to a SkWStream. Returns true on success @@ -189,13 +190,18 @@ class SK_API SkWStream : SkNoncopyable { virtual void newline(); virtual void flush(); + virtual size_t bytesWritten() const = 0; + // helpers bool write8(U8CPU); bool write16(U16CPU); bool write32(uint32_t); - bool writeText(const char text[]); + bool writeText(const char text[]) { + SkASSERT(text); + return this->write(text, strlen(text)); + } bool writeDecAsText(int32_t); bool writeBigDecAsText(int64_t, int minDigits = 0); bool writeHexAsText(uint32_t, int minDigits = 0); @@ -205,17 +211,13 @@ class SK_API SkWStream : SkNoncopyable { bool writeScalar(SkScalar); bool writePackedUInt(size_t); - bool writeStream(SkStream* input, size_t length); + bool writeStream(SkStream* input, size_t length); /** - * Append an SkData object to the stream, such that it can be read - * out of the stream using SkStream::readData(). - * - * Note that the encoding method used to write the SkData object - * to the stream may change over time. This method DOES NOT - * just write the raw content of the SkData object to the stream. + * This returns the number of bytes in the stream required to store + * 'value'. */ - bool writeData(const SkData*); + static int SizeOfPackedUInt(size_t value); }; //////////////////////////////////////////////////////////////////////////////////////// @@ -223,13 +225,9 @@ class SK_API SkWStream : SkNoncopyable { #include "SkString.h" #include -struct SkFILE; - /** A stream that wraps a C FILE* file stream. */ class SK_API SkFILEStream : public SkStreamAsset { public: - SK_DECLARE_INST_COUNT(SkFILEStream) - /** Initialize the stream by calling sk_fopen on the specified path. * This internal stream will be closed in the destructor. */ @@ -256,35 +254,33 @@ class SK_API SkFILEStream : public SkStreamAsset { */ void setPath(const char path[]); - virtual size_t read(void* buffer, size_t size) SK_OVERRIDE; - virtual bool isAtEnd() const SK_OVERRIDE; + size_t read(void* buffer, size_t size) override; + bool isAtEnd() const override; - virtual bool rewind() SK_OVERRIDE; - virtual SkStreamAsset* duplicate() const SK_OVERRIDE; + bool rewind() override; + SkStreamAsset* duplicate() const override; - virtual size_t getPosition() const SK_OVERRIDE; - virtual bool seek(size_t position) SK_OVERRIDE; - virtual bool move(long offset) SK_OVERRIDE; - virtual SkStreamAsset* fork() const SK_OVERRIDE; + size_t getPosition() const override; + bool seek(size_t position) override; + bool move(long offset) override; + SkStreamAsset* fork() const override; - virtual size_t getLength() const SK_OVERRIDE; + size_t getLength() const override; - virtual const void* getMemoryBase() SK_OVERRIDE; + const void* getMemoryBase() override; private: - SkFILE* fFILE; + FILE* fFILE; SkString fName; Ownership fOwnership; // fData is lazilly initialized when needed. - mutable SkAutoTUnref fData; + mutable sk_sp fData; typedef SkStreamAsset INHERITED; }; class SK_API SkMemoryStream : public SkStreamMemory { public: - SK_DECLARE_INST_COUNT(SkMemoryStream) - SkMemoryStream(); /** We allocate (and free) the memory. Write to it via getMemoryBase() */ @@ -293,12 +289,8 @@ class SK_API SkMemoryStream : public SkStreamMemory { /** If copyData is true, the stream makes a private copy of the data. */ SkMemoryStream(const void* data, size_t length, bool copyData = false); - /** Use the specified data as the memory for this stream. - * The stream will call ref() on the data (assuming it is not NULL). - */ - SkMemoryStream(SkData*); - - virtual ~SkMemoryStream(); + /** Creates the stream to read from the specified data */ + SkMemoryStream(sk_sp); /** Resets the stream to the specified data and length, just like the constructor. @@ -312,40 +304,32 @@ class SK_API SkMemoryStream : public SkStreamMemory { */ void setMemoryOwned(const void* data, size_t length); - /** Return the stream's data in a SkData. - * The caller must call unref() when it is finished using the data. - */ - SkData* copyToData() const; - - /** - * Use the specified data as the memory for this stream. - * The stream will call ref() on the data (assuming it is not NULL). - * The function returns the data parameter as a convenience. - */ - SkData* setData(SkData*); + sk_sp asData() const { return fData; } + void setData(sk_sp); void skipToAlign4(); const void* getAtPos(); - size_t peek() const { return fOffset; } - virtual size_t read(void* buffer, size_t size) SK_OVERRIDE; - virtual bool isAtEnd() const SK_OVERRIDE; + size_t read(void* buffer, size_t size) override; + bool isAtEnd() const override; + + size_t peek(void* buffer, size_t size) const override; - virtual bool rewind() SK_OVERRIDE; - virtual SkMemoryStream* duplicate() const SK_OVERRIDE; + bool rewind() override; + SkMemoryStream* duplicate() const override; - virtual size_t getPosition() const SK_OVERRIDE; - virtual bool seek(size_t position) SK_OVERRIDE; - virtual bool move(long offset) SK_OVERRIDE; - virtual SkMemoryStream* fork() const SK_OVERRIDE; + size_t getPosition() const override; + bool seek(size_t position) override; + bool move(long offset) override; + SkMemoryStream* fork() const override; - virtual size_t getLength() const SK_OVERRIDE; + size_t getLength() const override; - virtual const void* getMemoryBase() SK_OVERRIDE; + const void* getMemoryBase() override; private: - SkData* fData; - size_t fOffset; + sk_sp fData; + size_t fOffset; typedef SkStreamMemory INHERITED; }; @@ -354,8 +338,6 @@ class SK_API SkMemoryStream : public SkStreamMemory { class SK_API SkFILEWStream : public SkWStream { public: - SK_DECLARE_INST_COUNT(SkFILEWStream) - SkFILEWStream(const char path[]); virtual ~SkFILEWStream(); @@ -363,22 +345,22 @@ class SK_API SkFILEWStream : public SkWStream { */ bool isValid() const { return fFILE != NULL; } - virtual bool write(const void* buffer, size_t size) SK_OVERRIDE; - virtual void flush() SK_OVERRIDE; + bool write(const void* buffer, size_t size) override; + void flush() override; + void fsync(); + size_t bytesWritten() const override; private: - SkFILE* fFILE; + FILE* fFILE; typedef SkWStream INHERITED; }; -class SkMemoryWStream : public SkWStream { +class SK_API SkMemoryWStream : public SkWStream { public: - SK_DECLARE_INST_COUNT(SkMemoryWStream) - SkMemoryWStream(void* buffer, size_t size); - virtual bool write(const void* buffer, size_t size) SK_OVERRIDE; - size_t bytesWritten() const { return fBytesWritten; } + bool write(const void* buffer, size_t size) override; + size_t bytesWritten() const override { return fBytesWritten; } private: char* fBuffer; @@ -390,27 +372,24 @@ class SkMemoryWStream : public SkWStream { class SK_API SkDynamicMemoryWStream : public SkWStream { public: - SK_DECLARE_INST_COUNT(SkDynamicMemoryWStream) - SkDynamicMemoryWStream(); virtual ~SkDynamicMemoryWStream(); - virtual bool write(const void* buffer, size_t size) SK_OVERRIDE; + bool write(const void* buffer, size_t size) override; + size_t bytesWritten() const override { return fBytesWritten; } // random access write // modifies stream and returns true if offset + size is less than or equal to getOffset() bool write(const void* buffer, size_t offset, size_t size); bool read(void* buffer, size_t offset, size_t size); size_t getOffset() const { return fBytesWritten; } - size_t bytesWritten() const { return fBytesWritten; } // copy what has been written to the stream into dst void copyTo(void* dst) const; + void writeToStream(SkWStream* dst) const; - /** - * Return a copy of the data written so far. This call is responsible for - * calling unref() when they are finished with the data. - */ - SkData* copyToData() const; + sk_sp snapshotAsData() const; + // Return the contents as SkData, and then reset the stream. + sk_sp detachAsData(); /** Reset, returning a reader stream with the current content. */ SkStreamAsset* detachAsStream(); @@ -423,7 +402,7 @@ class SK_API SkDynamicMemoryWStream : public SkWStream { Block* fHead; Block* fTail; size_t fBytesWritten; - mutable SkData* fCopy; // is invalidated if we write after it is created + mutable sk_sp fCopy; // is invalidated if we write after it is created void invalidateCopy(); @@ -437,13 +416,15 @@ class SK_API SkDynamicMemoryWStream : public SkWStream { class SK_API SkDebugWStream : public SkWStream { public: - SK_DECLARE_INST_COUNT(SkDebugWStream) + SkDebugWStream() : fBytesWritten(0) {} // overrides - virtual bool write(const void* buffer, size_t size) SK_OVERRIDE; - virtual void newline() SK_OVERRIDE; + bool write(const void* buffer, size_t size) override; + void newline() override; + size_t bytesWritten() const override { return fBytesWritten; } private: + size_t fBytesWritten; typedef SkWStream INHERITED; }; diff --git a/libskia/include/core/SkString.h b/libskia/include/core/SkString.h index bc06cb0a..4a2d91f2 100644 --- a/libskia/include/core/SkString.h +++ b/libskia/include/core/SkString.h @@ -10,8 +10,8 @@ #ifndef SkString_DEFINED #define SkString_DEFINED +#include "../private/SkTArray.h" #include "SkScalar.h" -#include "SkTArray.h" #include @@ -36,7 +36,13 @@ int SkStrStartsWithOneOf(const char string[], const char prefixes[]); static int SkStrFind(const char string[], const char substring[]) { const char *first = strstr(string, substring); if (NULL == first) return -1; - return SkToS32(first - &string[0]); + return SkToInt(first - &string[0]); +} + +static int SkStrFindLastOf(const char string[], const char subchar) { + const char* last = strrchr(string, subchar); + if (NULL == last) return -1; + return SkToInt(last - &string[0]); } static bool SkStrContains(const char string[], const char substring[]) { @@ -58,7 +64,23 @@ static inline char *SkStrDup(const char string[]) { return ret; } - +/* + * The SkStrAppend... methods will write into the provided buffer, assuming it is large enough. + * Each method has an associated const (e.g. SkStrAppendU32_MaxSize) which will be the largest + * value needed for that method's buffer. + * + * char storage[SkStrAppendU32_MaxSize]; + * SkStrAppendU32(storage, value); + * + * Note : none of the SkStrAppend... methods write a terminating 0 to their buffers. Instead, + * the methods return the ptr to the end of the written part of the buffer. This can be used + * to compute the length, and/or know where to write a 0 if that is desired. + * + * char storage[SkStrAppendU32_MaxSize + 1]; + * char* stop = SkStrAppendU32(storage, value); + * size_t len = stop - storage; + * *stop = 0; // valid, since storage was 1 byte larger than the max. + */ #define SkStrAppendU32_MaxSize 10 char* SkStrAppendU32(char buffer[], uint32_t); @@ -89,7 +111,6 @@ char* SkStrAppendS64(char buffer[], int64_t, int minDigits); #define SkStrAppendScalar SkStrAppendFloat char* SkStrAppendFloat(char buffer[], float); -char* SkStrAppendFixed(char buffer[], SkFixed); /** \class SkString @@ -104,6 +125,7 @@ class SK_API SkString { explicit SkString(const char text[]); SkString(const char text[], size_t len); SkString(const SkString&); + SkString(SkString&&); ~SkString(); bool isEmpty() const { return 0 == fRec->fLength; } @@ -136,6 +158,9 @@ class SK_API SkString { int find(const char substring[]) const { return SkStrFind(fRec->data(), substring); } + int findLastOf(const char subchar) const { + return SkStrFindLastOf(fRec->data(), subchar); + } friend bool operator==(const SkString& a, const SkString& b) { return a.equals(b); @@ -147,12 +172,14 @@ class SK_API SkString { // these methods edit the string SkString& operator=(const SkString&); + SkString& operator=(SkString&&); SkString& operator=(const char text[]); char* writable_str(); char& operator[](size_t n) { return this->writable_str()[n]; } void reset(); + /** Destructive resize, does not preserve contents. */ void resize(size_t len) { this->set(NULL, len); } void set(const SkString& src) { *this = src; } void set(const char text[]); @@ -195,6 +222,7 @@ class SK_API SkString { void appendf(const char format[], ...) SK_PRINTF_LIKE(2, 3); void appendVAList(const char format[], va_list); void prependf(const char format[], ...) SK_PRINTF_LIKE(2, 3); + void prependVAList(const char format[], va_list); void remove(size_t offset, size_t length); @@ -221,7 +249,6 @@ class SK_API SkString { Rec* fRec; #ifdef SK_DEBUG - const char* fStr; void validate() const; #else void validate() const {} @@ -241,7 +268,22 @@ template <> inline void SkTSwap(SkString& a, SkString& b) { a.swap(b); } +enum SkStrSplitMode { + // Strictly return all results. If the input is ",," and the separator is ',' this will return + // an array of three empty strings. + kStrict_SkStrSplitMode, + + // Only nonempty results will be added to the results. Multiple separators will be + // coalesced. Separators at the beginning and end of the input will be ignored. If the input is + // ",," and the separator is ',', this will return an empty vector. + kCoalesce_SkStrSplitMode +}; + // Split str on any characters in delimiters into out. (Think, strtok with a sane API.) -void SkStrSplit(const char* str, const char* delimiters, SkTArray* out); +void SkStrSplit(const char* str, const char* delimiters, SkStrSplitMode splitMode, + SkTArray* out); +inline void SkStrSplit(const char* str, const char* delimiters, SkTArray* out) { + SkStrSplit(str, delimiters, kCoalesce_SkStrSplitMode, out); +} #endif diff --git a/libskia/include/core/SkStrokeRec.h b/libskia/include/core/SkStrokeRec.h index 1e0ec880..9a49a3da 100644 --- a/libskia/include/core/SkStrokeRec.h +++ b/libskia/include/core/SkStrokeRec.h @@ -12,6 +12,7 @@ class SkPath; +SK_BEGIN_REQUIRE_DENSE class SkStrokeRec { public: enum InitStyle { @@ -19,9 +20,8 @@ class SkStrokeRec { kFill_InitStyle }; SkStrokeRec(InitStyle style); - - SkStrokeRec(const SkStrokeRec&); - explicit SkStrokeRec(const SkPaint&); + SkStrokeRec(const SkPaint&, SkPaint::Style, SkScalar resScale = 1); + explicit SkStrokeRec(const SkPaint&, SkScalar resScale = 1); enum Style { kHairline_Style, @@ -29,12 +29,15 @@ class SkStrokeRec { kStroke_Style, kStrokeAndFill_Style }; + enum { + kStyleCount = kStrokeAndFill_Style + 1 + }; Style getStyle() const; SkScalar getWidth() const { return fWidth; } SkScalar getMiter() const { return fMiterLimit; } - SkPaint::Cap getCap() const { return fCap; } - SkPaint::Join getJoin() const { return fJoin; } + SkPaint::Cap getCap() const { return (SkPaint::Cap)fCap; } + SkPaint::Join getJoin() const { return (SkPaint::Join)fJoin; } bool isHairlineStyle() const { return kHairline_Style == this->getStyle(); @@ -60,6 +63,15 @@ class SkStrokeRec { fMiterLimit = miterLimit; } + SkScalar getResScale() const { + return fResScale; + } + + void setResScale(SkScalar rs) { + SkASSERT(rs > 0 && SkScalarIsFinite(rs)); + fResScale = rs; + } + /** * Returns true if this specifes any thick stroking, i.e. applyToPath() * will return true. @@ -81,20 +93,59 @@ class SkStrokeRec { */ bool applyToPath(SkPath* dst, const SkPath& src) const; - bool operator==(const SkStrokeRec& other) const { - return fWidth == other.fWidth && - fMiterLimit == other.fMiterLimit && - fCap == other.fCap && - fJoin == other.fJoin && - fStrokeAndFill == other.fStrokeAndFill; + /** + * Apply these stroke parameters to a paint. + */ + void applyToPaint(SkPaint* paint) const; + + /** + * Gives a conservative value for the outset that should applied to a + * geometries bounds to account for any inflation due to applying this + * strokeRec to the geometry. + */ + SkScalar getInflationRadius() const; + + /** + * Equivalent to: + * SkStrokeRec rec(paint, style); + * rec.getInflationRadius(); + * This does not account for other effects on the paint (i.e. path + * effect). + */ + static SkScalar GetInflationRadius(const SkPaint&, SkPaint::Style); + + /** + * Compare if two SkStrokeRecs have an equal effect on a path. + * Equal SkStrokeRecs produce equal paths. Equality of produced + * paths does not take the ResScale parameter into account. + */ + bool hasEqualEffect(const SkStrokeRec& other) const { + if (!this->needToApply()) { + return this->getStyle() == other.getStyle(); + } + return fWidth == other.fWidth && + fMiterLimit == other.fMiterLimit && + fCap == other.fCap && + fJoin == other.fJoin && + fStrokeAndFill == other.fStrokeAndFill; } private: + void init(const SkPaint&, SkPaint::Style, SkScalar resScale); + + SkScalar fResScale; SkScalar fWidth; SkScalar fMiterLimit; - SkPaint::Cap fCap; - SkPaint::Join fJoin; - bool fStrokeAndFill; + // The following three members are packed together into a single u32. + // This is to avoid unnecessary padding and ensure binary equality for + // hashing (because the padded areas might contain garbage values). + // + // fCap and fJoin are larger than needed to avoid having to initialize + // any pad values + uint32_t fCap : 16; // SkPaint::Cap + uint32_t fJoin : 15; // SkPaint::Join + uint32_t fStrokeAndFill : 1; // bool }; +SK_END_REQUIRE_DENSE #endif diff --git a/libskia/include/core/SkSurface.h b/libskia/include/core/SkSurface.h index 3b7df425..eb8f6aef 100644 --- a/libskia/include/core/SkSurface.h +++ b/libskia/include/core/SkSurface.h @@ -10,6 +10,7 @@ #include "SkRefCnt.h" #include "SkImage.h" +#include "SkSurfaceProps.h" class SkCanvas; class SkPaint; @@ -23,58 +24,133 @@ class GrRenderTarget; * * To draw into a canvas, first create the appropriate type of Surface, and * then request the canvas from the surface. + * + * SkSurface always has non-zero dimensions. If there is a request for a new surface, and either + * of the requested dimensions are zero, then NULL will be returned. */ class SK_API SkSurface : public SkRefCnt { public: - SK_DECLARE_INST_COUNT(SkSurface) - /** * Create a new surface, using the specified pixels/rowbytes as its * backend. * * If the requested surface cannot be created, or the request is not a * supported configuration, NULL will be returned. + * + * Callers are responsible for initialiazing the surface pixels. + */ + static sk_sp MakeRasterDirect(const SkImageInfo&, void* pixels, size_t rowBytes, + const SkSurfaceProps* = nullptr); + + /** + * The same as NewRasterDirect, but also accepts a call-back routine, which is invoked + * when the surface is deleted, and is passed the pixel memory and the specified context. */ - static SkSurface* NewRasterDirect(const SkImageInfo&, void* pixels, size_t rowBytes); + static sk_sp MakeRasterDirectReleaseProc(const SkImageInfo&, void* pixels, size_t rowBytes, + void (*releaseProc)(void* pixels, void* context), + void* context, const SkSurfaceProps* = nullptr); /** - * Return a new surface, with the memory for the pixels automatically - * allocated. + * Return a new surface, with the memory for the pixels automatically allocated and + * zero-initialized, but respecting the specified rowBytes. If rowBytes==0, then a default + * value will be chosen. If a non-zero rowBytes is specified, then any images snapped off of + * this surface (via makeImageSnapshot()) are guaranteed to have the same rowBytes. * * If the requested surface cannot be created, or the request is not a * supported configuration, NULL will be returned. */ - static SkSurface* NewRaster(const SkImageInfo&); + static sk_sp MakeRaster(const SkImageInfo&, size_t rowBytes, const SkSurfaceProps*); + + /** + * Allocate a new surface, automatically computing the rowBytes. + */ + static sk_sp MakeRaster(const SkImageInfo& info, + const SkSurfaceProps* props = nullptr) { + return MakeRaster(info, 0, props); + } /** * Helper version of NewRaster. It creates a SkImageInfo with the * specified width and height, and populates the rest of info to match * pixels in SkPMColor format. */ - static SkSurface* NewRasterPMColor(int width, int height) { - SkImageInfo info = { - width, height, kPMColor_SkColorType, kPremul_SkAlphaType - }; - return NewRaster(info); + static sk_sp MakeRasterN32Premul(int width, int height, + const SkSurfaceProps* props = nullptr) { + return MakeRaster(SkImageInfo::MakeN32Premul(width, height), props); } /** - * Return a new surface whose contents will be recorded into a picture. - * When this surface is drawn into another canvas, its contents will be - * "replayed" into that canvas. + * Used to wrap a pre-existing backend 3D API texture as a SkSurface. The kRenderTarget flag + * must be set on GrBackendTextureDesc for this to succeed. Skia will not assume ownership + * of the texture and the client must ensure the texture is valid for the lifetime of the + * SkSurface. + */ + static sk_sp MakeFromBackendTexture(GrContext*, const GrBackendTextureDesc&, + sk_sp, const SkSurfaceProps*); + + /** + * Used to wrap a pre-existing 3D API rendering target as a SkSurface. Skia will not assume + * ownership of the render target and the client must ensure the render target is valid for the + * lifetime of the SkSurface. + */ + static sk_sp MakeFromBackendRenderTarget(GrContext*, + const GrBackendRenderTargetDesc&, + sk_sp, + const SkSurfaceProps*); + + /** + * Used to wrap a pre-existing 3D API texture as a SkSurface. Skia will treat the texture as + * a rendering target only, but unlike NewFromBackendRenderTarget, Skia will manage and own + * the associated render target objects (but not the provided texture). The kRenderTarget flag + * must be set on GrBackendTextureDesc for this to succeed. Skia will not assume ownership + * of the texture and the client must ensure the texture is valid for the lifetime of the + * SkSurface. */ - static SkSurface* NewPicture(int width, int height); + static sk_sp MakeFromBackendTextureAsRenderTarget( + GrContext*, const GrBackendTextureDesc&, sk_sp, const SkSurfaceProps*); /** - * Return a new surface using the specified render target. + * Legacy versions of the above factories, without color space support. These create "legacy" + * surfaces that operate without gamma correction or color management. */ - static SkSurface* NewRenderTargetDirect(GrContext*, GrRenderTarget*); + static sk_sp MakeFromBackendTexture(GrContext* ctx, const GrBackendTextureDesc& desc, + const SkSurfaceProps* props) { + return MakeFromBackendTexture(ctx, desc, nullptr, props); + } + + static sk_sp MakeFromBackendRenderTarget(GrContext* ctx, + const GrBackendRenderTargetDesc& desc, + const SkSurfaceProps* props) { + return MakeFromBackendRenderTarget(ctx, desc, nullptr, props); + } + + static sk_sp MakeFromBackendTextureAsRenderTarget( + GrContext* ctx, const GrBackendTextureDesc& desc, const SkSurfaceProps* props) { + return MakeFromBackendTextureAsRenderTarget(ctx, desc, nullptr, props); + } + /** * Return a new surface whose contents will be drawn to an offscreen * render target, allocated by the surface. */ - static SkSurface* NewRenderTarget(GrContext*, const SkImageInfo&, int sampleCount = 0); + static sk_sp MakeRenderTarget(GrContext*, SkBudgeted, const SkImageInfo&, + int sampleCount, GrSurfaceOrigin, + const SkSurfaceProps*); + + static sk_sp MakeRenderTarget(GrContext* context, SkBudgeted budgeted, + const SkImageInfo& info, int sampleCount, + const SkSurfaceProps* props) { + return MakeRenderTarget(context, budgeted, info, sampleCount, + kBottomLeft_GrSurfaceOrigin, props); + } + + static sk_sp MakeRenderTarget(GrContext* gr, SkBudgeted b, const SkImageInfo& info) { + if (!info.width() || !info.height()) { + return nullptr; + } + return MakeRenderTarget(gr, b, info, 0, kBottomLeft_GrSurfaceOrigin, nullptr); + } int width() const { return fWidth; } int height() const { return fHeight; } @@ -109,9 +185,45 @@ class SK_API SkSurface : public SkRefCnt { /** * Call this if the contents are about to change. This will (lazily) force a new * value to be returned from generationID() when it is called next. + * + * CAN WE DEPRECATE THIS? */ void notifyContentWillChange(ContentChangeMode mode); + enum BackendHandleAccess { + kFlushRead_BackendHandleAccess, //!< caller may read from the backend object + kFlushWrite_BackendHandleAccess, //!< caller may write to the backend object + kDiscardWrite_BackendHandleAccess, //!< caller must over-write the entire backend object + }; + + /* + * These are legacy aliases which will be removed soon + */ + static const BackendHandleAccess kFlushRead_TextureHandleAccess = + kFlushRead_BackendHandleAccess; + static const BackendHandleAccess kFlushWrite_TextureHandleAccess = + kFlushWrite_BackendHandleAccess; + static const BackendHandleAccess kDiscardWrite_TextureHandleAccess = + kDiscardWrite_BackendHandleAccess; + + + /** + * Retrieves the backend API handle of the texture used by this surface, or 0 if the surface + * is not backed by a GPU texture. + * + * The returned texture-handle is only valid until the next draw-call into the surface, + * or the surface is deleted. + */ + GrBackendObject getTextureHandle(BackendHandleAccess); + + /** + * Retrieves the backend API handle of the RenderTarget backing this surface. Callers must + * ensure this function returns 'true' or else the GrBackendObject will be invalid + * + * In OpenGL this will return the FramebufferObject ID. + */ + bool getRenderTargetHandle(GrBackendObject*, BackendHandleAccess); + /** * Return a canvas that will draw into this surface. This will always * return the same canvas for a given surface, and is manged/owned by the @@ -133,17 +245,31 @@ class SK_API SkSurface : public SkRefCnt { * ... // draw using canvasB * canvasA->drawSurface(surfaceB); // <--- this will always be optimal! */ - SkSurface* newSurface(const SkImageInfo&); + sk_sp makeSurface(const SkImageInfo&); /** * Returns an image of the current state of the surface pixels up to this * point. Subsequent changes to the surface (by drawing into its canvas) - * will not be reflected in this image. + * will not be reflected in this image. If a copy must be made the Budgeted + * parameter controls whether it counts against the resource budget + * (currently for the gpu backend only). */ - SkImage* newImageSnapshot(); + sk_sp makeImageSnapshot(SkBudgeted = SkBudgeted::kYes); /** - * Thought the caller could get a snapshot image explicitly, and draw that, + * In rare instances a client may want a unique copy of the SkSurface's contents in an image + * snapshot. This enum can be used to enforce that the image snapshot's backing store is not + * shared with another image snapshot or the surface's backing store. This is generally more + * expensive. This was added for Chromium bug 585250. + */ + enum ForceUnique { + kNo_ForceUnique, + kYes_ForceUnique + }; + sk_sp makeImageSnapshot(SkBudgeted, ForceUnique); + + /** + * Though the caller could get a snapshot image explicitly, and draw that, * it seems that directly drawing a surface into another canvas might be * a common pattern, and that we could possibly be more efficient, since * we'd know that the "snapshot" need only live until we've handed it off @@ -151,8 +277,48 @@ class SK_API SkSurface : public SkRefCnt { */ void draw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*); + /** + * If the surface has direct access to its pixels (i.e. they are in local + * RAM) return true, and if not null, set the pixmap parameter to point to the information + * about the surface's pixels. The pixel address in the pixmap is only valid while + * the surface object is in scope, and no API call is made on the surface + * or its canvas. + * + * On failure, returns false and the pixmap parameter is ignored. + */ + bool peekPixels(SkPixmap*); + + /** + * Copy the pixels from the surface into the specified buffer (pixels + rowBytes), + * converting them into the requested format (dstInfo). The surface pixels are read + * starting at the specified (srcX,srcY) location. + * + * The specified ImageInfo and (srcX,srcY) offset specifies a source rectangle + * + * srcR.setXYWH(srcX, srcY, dstInfo.width(), dstInfo.height()); + * + * srcR is intersected with the bounds of the base-layer. If this intersection is not empty, + * then we have two sets of pixels (of equal size). Replace the dst pixels with the + * corresponding src pixels, performing any colortype/alphatype transformations needed + * (in the case where the src and dst have different colortypes or alphatypes). + * + * This call can fail, returning false, for several reasons: + * - If srcR does not intersect the surface bounds. + * - If the requested colortype/alphatype cannot be converted from the surface's types. + */ + bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes, + int srcX, int srcY); + + const SkSurfaceProps& props() const { return fProps; } + + /** + * Issue any pending surface IO to the current backend 3D API and resolve any surface MSAA. + */ + void prepareForExternalIO(); + protected: - SkSurface(int width, int height); + SkSurface(int width, int height, const SkSurfaceProps*); + SkSurface(const SkImageInfo&, const SkSurfaceProps*); // called by subclass if their contents have changed void dirtyGenerationID() { @@ -160,9 +326,10 @@ class SK_API SkSurface : public SkRefCnt { } private: - const int fWidth; - const int fHeight; - uint32_t fGenerationID; + const SkSurfaceProps fProps; + const int fWidth; + const int fHeight; + uint32_t fGenerationID; typedef SkRefCnt INHERITED; }; diff --git a/libskia/include/core/SkSurfaceProps.h b/libskia/include/core/SkSurfaceProps.h new file mode 100644 index 00000000..da04d1fe --- /dev/null +++ b/libskia/include/core/SkSurfaceProps.h @@ -0,0 +1,82 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkSurfaceProps_DEFINED +#define SkSurfaceProps_DEFINED + +#include "SkTypes.h" + +/** + * Description of how the LCD strips are arranged for each pixel. If this is unknown, or the + * pixels are meant to be "portable" and/or transformed before showing (e.g. rotated, scaled) + * then use kUnknown_SkPixelGeometry. + */ +enum SkPixelGeometry { + kUnknown_SkPixelGeometry, + kRGB_H_SkPixelGeometry, + kBGR_H_SkPixelGeometry, + kRGB_V_SkPixelGeometry, + kBGR_V_SkPixelGeometry, +}; + +// Returns true iff geo is a known geometry and is RGB. +static inline bool SkPixelGeometryIsRGB(SkPixelGeometry geo) { + return kRGB_H_SkPixelGeometry == geo || kRGB_V_SkPixelGeometry == geo; +} + +// Returns true iff geo is a known geometry and is BGR. +static inline bool SkPixelGeometryIsBGR(SkPixelGeometry geo) { + return kBGR_H_SkPixelGeometry == geo || kBGR_V_SkPixelGeometry == geo; +} + +// Returns true iff geo is a known geometry and is horizontal. +static inline bool SkPixelGeometryIsH(SkPixelGeometry geo) { + return kRGB_H_SkPixelGeometry == geo || kBGR_H_SkPixelGeometry == geo; +} + +// Returns true iff geo is a known geometry and is vertical. +static inline bool SkPixelGeometryIsV(SkPixelGeometry geo) { + return kRGB_V_SkPixelGeometry == geo || kBGR_V_SkPixelGeometry == geo; +} + +/** + * Describes properties and constraints of a given SkSurface. The rendering engine can parse these + * during drawing, and can sometimes optimize its performance (e.g. disabling an expensive + * feature). + */ +class SK_API SkSurfaceProps { +public: + enum Flags { + kUseDeviceIndependentFonts_Flag = 1 << 0, + }; + /** Deprecated alias used by Chromium. Will be removed. */ + static const Flags kUseDistanceFieldFonts_Flag = kUseDeviceIndependentFonts_Flag; + + SkSurfaceProps(uint32_t flags, SkPixelGeometry); + + enum InitType { + kLegacyFontHost_InitType + }; + SkSurfaceProps(InitType); + SkSurfaceProps(uint32_t flags, InitType); + SkSurfaceProps(const SkSurfaceProps& other); + + uint32_t flags() const { return fFlags; } + SkPixelGeometry pixelGeometry() const { return fPixelGeometry; } + + bool isUseDeviceIndependentFonts() const { + return SkToBool(fFlags & kUseDeviceIndependentFonts_Flag); + } + +private: + SkSurfaceProps(); + + uint32_t fFlags; + SkPixelGeometry fPixelGeometry; +}; + +#endif diff --git a/libskia/include/core/SkSwizzle.h b/libskia/include/core/SkSwizzle.h new file mode 100644 index 00000000..253f4e39 --- /dev/null +++ b/libskia/include/core/SkSwizzle.h @@ -0,0 +1,19 @@ +/* + * Copyright 2016 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkSwizzle_DEFINED +#define SkSwizzle_DEFINED + +#include "SkTypes.h" + +/** + Swizzles byte order of |count| 32-bit pixels, swapping R and B. + (RGBA <-> BGRA) +*/ +SK_API void SkSwapRB(uint32_t* dest, const uint32_t* src, int count); + +#endif diff --git a/libskia/include/core/SkTLazy.h b/libskia/include/core/SkTLazy.h index 2147b668..cb08387b 100644 --- a/libskia/include/core/SkTLazy.h +++ b/libskia/include/core/SkTLazy.h @@ -1,4 +1,3 @@ - /* * Copyright 2011 Google Inc. * @@ -6,16 +5,13 @@ * found in the LICENSE file. */ - - #ifndef SkTLazy_DEFINED #define SkTLazy_DEFINED +#include "../private/SkTemplates.h" #include "SkTypes.h" #include - -template class SkTLazy; -template void* operator new(size_t, SkTLazy* lazy); +#include /** * Efficient way to defer allocating/initializing a class until it is needed @@ -23,21 +19,12 @@ template void* operator new(size_t, SkTLazy* lazy); */ template class SkTLazy { public: - SkTLazy() : fPtr(NULL) {} + SkTLazy() : fPtr(nullptr) {} - explicit SkTLazy(const T* src) : fPtr(NULL) { - if (src) { - fPtr = new (fStorage) T(*src); - } - } + explicit SkTLazy(const T* src) + : fPtr(src ? new (fStorage.get()) T(*src) : nullptr) {} - SkTLazy(const SkTLazy& src) : fPtr(NULL) { - if (src.isValid()) { - fPtr = new (fStorage) T(*src->get()); - } else { - fPtr = NULL; - } - } + SkTLazy(const SkTLazy& src) : fPtr(nullptr) { *this = src; } ~SkTLazy() { if (this->isValid()) { @@ -45,17 +32,26 @@ template class SkTLazy { } } + SkTLazy& operator=(const SkTLazy& src) { + if (src.isValid()) { + this->set(*src.get()); + } else { + this->reset(); + } + return *this; + } + /** - * Return a pointer to a default-initialized instance of the class. If a - * previous instance had been initialized (either from init() or set()) it - * will first be destroyed, so that a freshly initialized instance is - * always returned. + * Return a pointer to an instance of the class initialized with 'args'. + * If a previous instance had been initialized (either from init() or + * set()) it will first be destroyed, so that a freshly initialized + * instance is always returned. */ - T* init() { + template T* init(Args&&... args) { if (this->isValid()) { fPtr->~T(); } - fPtr = new (SkTCast(fStorage)) T; + fPtr = new (SkTCast(fStorage.get())) T(std::forward(args)...); return fPtr; } @@ -69,16 +65,26 @@ template class SkTLazy { if (this->isValid()) { *fPtr = src; } else { - fPtr = new (SkTCast(fStorage)) T(src); + fPtr = new (SkTCast(fStorage.get())) T(src); } return fPtr; } + /** + * Destroy the lazy object (if it was created via init() or set()) + */ + void reset() { + if (this->isValid()) { + fPtr->~T(); + fPtr = nullptr; + } + } + /** * Returns true if a valid object has been initialized in the SkTLazy, * false otherwise. */ - bool isValid() const { return NULL != fPtr; } + bool isValid() const { return SkToBool(fPtr); } /** * Returns the object. This version should only be called when the caller @@ -88,32 +94,15 @@ template class SkTLazy { /** * Like above but doesn't assert if object isn't initialized (in which case - * NULL is returned). + * nullptr is returned). */ T* getMaybeNull() const { return fPtr; } private: - friend void* operator new(size_t, SkTLazy* lazy); - - T* fPtr; // NULL or fStorage - char fStorage[sizeof(T)]; + SkAlignedSTStorage<1, T> fStorage; + T* fPtr; // nullptr or fStorage }; -// Use the below macro (SkNEW_IN_TLAZY) rather than calling this directly -template void* operator new(size_t, SkTLazy* lazy) { - SkASSERT(!lazy->isValid()); - lazy->fPtr = reinterpret_cast(lazy->fStorage); - return lazy->fPtr; -} - -// Skia doesn't use C++ exceptions but it may be compiled with them enabled. Having an op delete -// to match the op new silences warnings about missing op delete when a constructor throws an -// exception. -template void operator delete(void*, SkTLazy*) { SK_CRASH(); } - -// Use this to construct a T inside an SkTLazy using a non-default constructor. -#define SkNEW_IN_TLAZY(tlazy_ptr, type_name, args) (new (tlazy_ptr) type_name args) - /** * A helper built on top of SkTLazy to do copy-on-first-write. The object is initialized * with a const pointer but provides a non-const pointer accessor. The first time the @@ -142,12 +131,14 @@ class SkTCopyOnFirstWrite { public: SkTCopyOnFirstWrite(const T& initial) : fObj(&initial) {} + SkTCopyOnFirstWrite(const T* initial) : fObj(initial) {} + // Constructor for delayed initialization. - SkTCopyOnFirstWrite() : fObj(NULL) {} + SkTCopyOnFirstWrite() : fObj(nullptr) {} // Should only be called once, and only if the default constructor was used. void init(const T& initial) { - SkASSERT(NULL == fObj); + SkASSERT(nullptr == fObj); SkASSERT(!fLazy.isValid()); fObj = &initial; } @@ -156,7 +147,7 @@ class SkTCopyOnFirstWrite { * Returns a writable T*. The first time this is called the initial object is cloned. */ T* writable() { - SkASSERT(NULL != fObj); + SkASSERT(fObj); if (!fLazy.isValid()) { fLazy.set(*fObj); fObj = fLazy.get(); diff --git a/libskia/include/core/SkTextBlob.h b/libskia/include/core/SkTextBlob.h new file mode 100644 index 00000000..8198f04a --- /dev/null +++ b/libskia/include/core/SkTextBlob.h @@ -0,0 +1,239 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkTextBlob_DEFINED +#define SkTextBlob_DEFINED + +#include "../private/SkTemplates.h" +#include "SkPaint.h" +#include "SkString.h" +#include "SkRefCnt.h" + +class SkReadBuffer; +class SkWriteBuffer; + +/** \class SkTextBlob + + SkTextBlob combines multiple text runs into an immutable, ref-counted structure. +*/ +class SK_API SkTextBlob final : public SkNVRefCnt { +public: + /** + * Returns a conservative blob bounding box. + */ + const SkRect& bounds() const { return fBounds; } + + /** + * Return a non-zero, unique value representing the text blob. + */ + uint32_t uniqueID() const { return fUniqueID; } + + /** + * Serialize to a buffer. + */ + void flatten(SkWriteBuffer&) const; + + /** + * Recreate an SkTextBlob that was serialized into a buffer. + * + * @param SkReadBuffer Serialized blob data. + * @return A new SkTextBlob representing the serialized data, or NULL if the buffer is + * invalid. + */ + static sk_sp MakeFromBuffer(SkReadBuffer&); + + static const SkTextBlob* CreateFromBuffer(SkReadBuffer& buffer) { + return MakeFromBuffer(buffer).release(); + } + + enum GlyphPositioning : uint8_t { + kDefault_Positioning = 0, // Default glyph advances -- zero scalars per glyph. + kHorizontal_Positioning = 1, // Horizontal positioning -- one scalar per glyph. + kFull_Positioning = 2 // Point positioning -- two scalars per glyph. + }; + +private: + friend class SkNVRefCnt; + class RunRecord; + + SkTextBlob(int runCount, const SkRect& bounds); + + ~SkTextBlob(); + + // Memory for objects of this class is created with sk_malloc rather than operator new and must + // be freed with sk_free. + void operator delete(void* p) { sk_free(p); } + void* operator new(size_t) { + SkFAIL("All blobs are created by placement new."); + return sk_malloc_throw(0); + } + void* operator new(size_t, void* p) { return p; } + + static unsigned ScalarsPerGlyph(GlyphPositioning pos); + + friend class SkTextBlobBuilder; + friend class SkTextBlobRunIterator; + + const int fRunCount; + const SkRect fBounds; + const uint32_t fUniqueID; + + SkDEBUGCODE(size_t fStorageSize;) + + // The actual payload resides in externally-managed storage, following the object. + // (see the .cpp for more details) + + typedef SkRefCnt INHERITED; +}; + +/** \class SkTextBlobBuilder + + Helper class for constructing SkTextBlobs. + */ +class SK_API SkTextBlobBuilder { +public: + SkTextBlobBuilder(); + + ~SkTextBlobBuilder(); + + /** + * Returns an immutable SkTextBlob for the current runs/glyphs. The builder is reset and + * can be reused. + */ + sk_sp make(); + + /** + * Glyph and position buffers associated with a run. + * + * A run is a sequence of glyphs sharing the same font metrics + * and positioning mode. + * + * If textByteCount is 0, utf8text and clusters will be NULL (no + * character information will be associated with the glyphs). + * + * utf8text will point to a buffer of size textByteCount bytes. + * + * clusters (if not NULL) will point to an array of size count. + * For each glyph, give the byte-offset into the text for the + * first byte in the first character in that glyph's cluster. + * Each value in the array should be an integer less than + * textByteCount. Values in the array should either be + * monotonically increasing (left-to-right text) or monotonically + * decreasing (right-to-left text). This definiton is conviently + * the same as used by Harfbuzz's hb_glyph_info_t::cluster field, + * except that Harfbuzz interleaves glyphs and clusters. + */ + struct RunBuffer { + SkGlyphID* glyphs; + SkScalar* pos; + char* utf8text; + uint32_t* clusters; + }; + + /** + * Allocates a new default-positioned run and returns its writable glyph buffer + * for direct manipulation. + * + * @param font The font to be used for this run. + * @param count Number of glyphs. + * @param x,y Position within the blob. + * @param textByteCount length of the original UTF-8 text that + * corresponds to this sequence of glyphs. If 0, + * text will not be included in the textblob. + * @param lang Language code, currently unimplemented. + * @param bounds Optional run bounding box. If known in advance (!= NULL), it will + * be used when computing the blob bounds, to avoid re-measuring. + * + * @return A writable glyph buffer, valid until the next allocRun() or + * build() call. The buffer is guaranteed to hold @count@ glyphs. + */ + const RunBuffer& allocRunText(const SkPaint& font, + int count, + SkScalar x, + SkScalar y, + int textByteCount, + SkString lang, + const SkRect* bounds = NULL); + const RunBuffer& allocRun(const SkPaint& font, int count, SkScalar x, SkScalar y, + const SkRect* bounds = NULL) { + return this->allocRunText(font, count, x, y, 0, SkString(), bounds); + } + + /** + * Allocates a new horizontally-positioned run and returns its writable glyph and position + * buffers for direct manipulation. + * + * @param font The font to be used for this run. + * @param count Number of glyphs. + * @param y Vertical offset within the blob. + * @param textByteCount length of the original UTF-8 text that + * corresponds to this sequence of glyphs. If 0, + * text will not be included in the textblob. + * @param lang Language code, currently unimplemented. + * @param bounds Optional run bounding box. If known in advance (!= NULL), it will + * be used when computing the blob bounds, to avoid re-measuring. + * + * @return Writable glyph and position buffers, valid until the next allocRun() + * or build() call. The buffers are guaranteed to hold @count@ elements. + */ + const RunBuffer& allocRunTextPosH(const SkPaint& font, int count, SkScalar y, + int textByteCount, SkString lang, + const SkRect* bounds = NULL); + const RunBuffer& allocRunPosH(const SkPaint& font, int count, SkScalar y, + const SkRect* bounds = NULL) { + return this->allocRunTextPosH(font, count, y, 0, SkString(), bounds); + } + + /** + * Allocates a new fully-positioned run and returns its writable glyph and position + * buffers for direct manipulation. + * + * @param font The font to be used for this run. + * @param count Number of glyphs. + * @param textByteCount length of the original UTF-8 text that + * corresponds to this sequence of glyphs. If 0, + * text will not be included in the textblob. + * @param lang Language code, currently unimplemented. + * @param bounds Optional run bounding box. If known in advance (!= NULL), it will + * be used when computing the blob bounds, to avoid re-measuring. + * + * @return Writable glyph and position buffers, valid until the next allocRun() + * or build() call. The glyph buffer and position buffer are + * guaranteed to hold @count@ and 2 * @count@ elements, respectively. + */ + const RunBuffer& allocRunTextPos(const SkPaint& font, int count, + int textByteCount, SkString lang, + const SkRect* bounds = NULL); + const RunBuffer& allocRunPos(const SkPaint& font, int count, + const SkRect* bounds = NULL) { + return this->allocRunTextPos(font, count, 0, SkString(), bounds); + } + +private: + void reserve(size_t size); + void allocInternal(const SkPaint& font, SkTextBlob::GlyphPositioning positioning, + int count, int textBytes, SkPoint offset, const SkRect* bounds); + bool mergeRun(const SkPaint& font, SkTextBlob::GlyphPositioning positioning, + int count, SkPoint offset); + void updateDeferredBounds(); + + static SkRect ConservativeRunBounds(const SkTextBlob::RunRecord&); + static SkRect TightRunBounds(const SkTextBlob::RunRecord&); + + SkAutoTMalloc fStorage; + size_t fStorageSize; + size_t fStorageUsed; + + SkRect fBounds; + int fRunCount; + bool fDeferredBounds; + size_t fLastRun; // index into fStorage + + RunBuffer fCurrentRunBuffer; +}; + +#endif // SkTextBlob_DEFINED diff --git a/libskia/include/core/SkThread.h b/libskia/include/core/SkThread.h deleted file mode 100644 index 412ace31..00000000 --- a/libskia/include/core/SkThread.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2006 The Android Open Source Project - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef SkThread_DEFINED -#define SkThread_DEFINED - -#include "SkTypes.h" - -// SK_ATOMICS_PLATFORM_H must provide inline implementations for the following declarations. - -/** Atomically adds one to the int referenced by addr and returns the previous value. - * No additional memory barrier is required; this must act as a compiler barrier. - */ -static int32_t sk_atomic_inc(int32_t* addr); - -/** Atomically adds inc to the int referenced by addr and returns the previous value. - * No additional memory barrier is required; this must act as a compiler barrier. - */ -static int32_t sk_atomic_add(int32_t* addr, int32_t inc); - -/** Atomically subtracts one from the int referenced by addr and returns the previous value. - * This must act as a release (SL/S) memory barrier and as a compiler barrier. - */ -static int32_t sk_atomic_dec(int32_t* addr); - -/** Atomically adds one to the int referenced by addr iff the referenced int was not 0 - * and returns the previous value. - * No additional memory barrier is required; this must act as a compiler barrier. - */ -static int32_t sk_atomic_conditional_inc(int32_t* addr); - -/** If sk_atomic_dec does not act as an acquire (L/SL) barrier, - * this must act as an acquire (L/SL) memory barrier and as a compiler barrier. - */ -static void sk_membar_acquire__after_atomic_dec(); - -/** If sk_atomic_conditional_inc does not act as an acquire (L/SL) barrier, - * this must act as an acquire (L/SL) memory barrier and as a compiler barrier. - */ -static void sk_membar_acquire__after_atomic_conditional_inc(); - -#include SK_ATOMICS_PLATFORM_H - - -/** SK_MUTEX_PLATFORM_H must provide the following (or equivalent) declarations. - -class SkBaseMutex { -public: - void acquire(); - void release(); -}; - -class SkMutex : SkBaseMutex { -public: - SkMutex(); - ~SkMutex(); -}; - -#define SK_DECLARE_STATIC_MUTEX(name) static SkBaseMutex name = ... -#define SK_DECLARE_GLOBAL_MUTEX(name) SkBaseMutex name = ... -*/ - -#include SK_MUTEX_PLATFORM_H - - -class SkAutoMutexAcquire : SkNoncopyable { -public: - explicit SkAutoMutexAcquire(SkBaseMutex& mutex) : fMutex(&mutex) { - SkASSERT(fMutex != NULL); - mutex.acquire(); - } - - explicit SkAutoMutexAcquire(SkBaseMutex* mutex) : fMutex(mutex) { - if (mutex) { - mutex->acquire(); - } - } - - /** If the mutex has not been released, release it now. */ - ~SkAutoMutexAcquire() { - if (fMutex) { - fMutex->release(); - } - } - - /** If the mutex has not been released, release it now. */ - void release() { - if (fMutex) { - fMutex->release(); - fMutex = NULL; - } - } - -private: - SkBaseMutex* fMutex; -}; -#define SkAutoMutexAcquire(...) SK_REQUIRE_LOCAL_VAR(SkAutoMutexAcquire) - -#endif diff --git a/libskia/include/core/SkTileGridPicture.h b/libskia/include/core/SkTileGridPicture.h deleted file mode 100644 index af7f0e2d..00000000 --- a/libskia/include/core/SkTileGridPicture.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2012 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef SkTileGridPicture_DEFINED -#define SkTileGridPicture_DEFINED - -#include "SkPicture.h" -#include "SkPoint.h" -#include "SkSize.h" - -/** - * Subclass of SkPicture that override the behavior of the - * kOptimizeForClippedPlayback_RecordingFlag by creating an SkTileGrid - * structure rather than an R-Tree. The tile grid has lower recording - * and playback costs, but is less effective at eliminating extraneous - * primitives for arbitrary query rectangles. It is most effective for - * tiled playback when the tile structure is known at record time. - */ -class SK_API SkTileGridPicture : public SkPicture { -public: - struct TileGridInfo { - /** Tile placement interval */ - SkISize fTileInterval; - - /** Pixel coverage overlap between adjacent tiles */ - SkISize fMargin; - - /** Offset added to device-space bounding box positions to convert - * them to tile-grid space. This can be used to adjust the "phase" - * of the tile grid to match probable query rectangles that will be - * used to search into the tile grid. As long as the offset is smaller - * or equal to the margin, there is no need to extend the domain of - * the tile grid to prevent data loss. - */ - SkIPoint fOffset; - }; - /** - * Constructor - * @param width recording canvas width in device pixels - * @param height recording canvas height in device pixels - * @param info description of the tiling layout - */ - SkTileGridPicture(int width, int height, const TileGridInfo& info); - - virtual SkBBoxHierarchy* createBBoxHierarchy() const SK_OVERRIDE; - -private: - int fXTileCount, fYTileCount; - TileGridInfo fInfo; -}; - -#endif diff --git a/libskia/include/core/SkTime.h b/libskia/include/core/SkTime.h index 51616d41..e9a89481 100644 --- a/libskia/include/core/SkTime.h +++ b/libskia/include/core/SkTime.h @@ -12,12 +12,16 @@ #include "SkTypes.h" +class SkString; + /** \class SkTime Platform-implemented utilities to return time of day, and millisecond counter. */ -class SkTime { +class SK_API SkTime { public: struct DateTime { + int16_t fTimeZoneMinutes; // The number of minutes that GetDateTime() + // is ahead of or behind UTC. uint16_t fYear; //!< e.g. 2005 uint8_t fMonth; //!< 1..12 uint8_t fDayOfWeek; //!< 0..6, 0==Sunday @@ -25,40 +29,32 @@ class SkTime { uint8_t fHour; //!< 0..23 uint8_t fMinute; //!< 0..59 uint8_t fSecond; //!< 0..59 + + void toISO8601(SkString* dst) const; }; static void GetDateTime(DateTime*); - static SkMSec GetMSecs(); + static double GetSecs() { return GetNSecs() * 1e-9; } + static double GetMSecs() { return GetNSecs() * 1e-6; } + static double GetNSecs(); }; -#if defined(SK_DEBUG) && defined(SK_BUILD_FOR_WIN32) - extern SkMSec gForceTickCount; -#endif - -#define SK_TIME_FACTOR 1 - /////////////////////////////////////////////////////////////////////////////// class SkAutoTime { public: // The label is not deep-copied, so its address must remain valid for the // lifetime of this object - SkAutoTime(const char* label = NULL, SkMSec minToDump = 0) : fLabel(label) - { - fNow = SkTime::GetMSecs(); - fMinToDump = minToDump; - } - ~SkAutoTime() - { - SkMSec dur = SkTime::GetMSecs() - fNow; - if (dur >= fMinToDump) { - SkDebugf("%s %d\n", fLabel ? fLabel : "", dur); - } + SkAutoTime(const char* label = nullptr) + : fLabel(label) + , fNow(SkTime::GetMSecs()) {} + ~SkAutoTime() { + uint64_t dur = static_cast(SkTime::GetMSecs() - fNow); + SkDebugf("%s %ld\n", fLabel ? fLabel : "", dur); } private: const char* fLabel; - SkMSec fNow; - SkMSec fMinToDump; + double fNow; }; #define SkAutoTime(...) SK_REQUIRE_LOCAL_VAR(SkAutoTime) diff --git a/libskia/include/core/SkTrace.h b/libskia/include/core/SkTrace.h deleted file mode 100644 index e6e7e2cc..00000000 --- a/libskia/include/core/SkTrace.h +++ /dev/null @@ -1,45 +0,0 @@ - -/* - * Copyright 2011 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef SkTrace_DEFINED -#define SkTrace_DEFINED - -#ifdef SK_USER_TRACE_INCLUDE_FILE - -/* If your system embeds skia and has complex event logging, in - src/config/SkUserConfig.h: - - define the three SK_TRACE_EVENT macros to map to your system's - equivalents, - - define the name of the include file in SK_USER_TRACE_INCLUDE_FILE - A trivial example is given in src/utils/SkDebugTrace.h. - - All arguments are const char*. Skia typically passes the name of - the object and function (and sometimes region of interest within - the function) separated by double colons for 'event'. - - SK_TRACE_EVENT1 and SK_TRACE_EVENT2 take one or two arbitrary - name-value pairs that you also want to log. SkStringPrintf() is useful - for formatting these values. - - For example: - SK_TRACE_EVENT0("GrContext::createAndLockTexture"); - SK_TRACE_EVENT1("GrDefaultPathRenderer::onDrawPath::renderPasses", - "verts", SkStringPrintf("%i", vert - base).c_str()); -*/ - - #include SK_USER_TRACE_INCLUDE_FILE - -#else - - #define SK_TRACE_EVENT0(event) - #define SK_TRACE_EVENT1(event, name1, value1) - #define SK_TRACE_EVENT2(event, name1, value1, name2, value2) - -#endif - -#endif diff --git a/libskia/include/core/SkTraceMemoryDump.h b/libskia/include/core/SkTraceMemoryDump.h new file mode 100644 index 00000000..8383190c --- /dev/null +++ b/libskia/include/core/SkTraceMemoryDump.h @@ -0,0 +1,80 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkTraceMemoryDump_DEFINED +#define SkTraceMemoryDump_DEFINED + +#include "SkTypes.h" + +class SkDiscardableMemory; + +/** + * Interface for memory tracing. + * This interface is meant to be passed as argument to the memory dump methods of Skia objects. + * The implementation of this interface is provided by the embedder. + */ +class SK_API SkTraceMemoryDump { +public: + /** + * Enum to specify the level of the requested details for the dump from the Skia objects. + */ + enum LevelOfDetail { + // Dump only the minimal details to get the total memory usage (Usually just the totals). + kLight_LevelOfDetail, + + // Dump the detailed breakdown of the objects in the caches. + kObjectsBreakdowns_LevelOfDetail + }; + + /** + * Appends a new memory dump (i.e. a row) to the trace memory infrastructure. + * If dumpName does not exist yet, a new one is created. Otherwise, a new column is appended to + * the previously created dump. + * Arguments: + * dumpName: an absolute, slash-separated, name for the item being dumped + * e.g., "skia/CacheX/EntryY". + * valueName: a string indicating the name of the column. + * e.g., "size", "active_size", "number_of_objects". + * This string is supposed to be long lived and is NOT copied. + * units: a string indicating the units for the value. + * e.g., "bytes", "objects". + * This string is supposed to be long lived and is NOT copied. + * value: the actual value being dumped. + */ + virtual void dumpNumericValue(const char* dumpName, + const char* valueName, + const char* units, + uint64_t value) = 0; + + /** + * Sets the memory backing for an existing dump. + * backingType and backingObjectId are used by the embedder to associate the memory dumped via + * dumpNumericValue with the corresponding dump that backs the memory. + */ + virtual void setMemoryBacking(const char* dumpName, + const char* backingType, + const char* backingObjectId) = 0; + + /** + * Specialization for memory backed by discardable memory. + */ + virtual void setDiscardableMemoryBacking( + const char* dumpName, + const SkDiscardableMemory& discardableMemoryObject) = 0; + + /** + * Returns the type of details requested in the dump. The granularity of the dump is supposed to + * match the LevelOfDetail argument. The level of detail must not affect the total size + * reported, but only granularity of the child entries. + */ + virtual LevelOfDetail getRequestedDetails() const = 0; + +protected: + virtual ~SkTraceMemoryDump() { } +}; + +#endif diff --git a/libskia/include/core/SkTypeface.h b/libskia/include/core/SkTypeface.h index d873e69b..51d5a0b1 100644 --- a/libskia/include/core/SkTypeface.h +++ b/libskia/include/core/SkTypeface.h @@ -1,4 +1,3 @@ - /* * Copyright 2006 The Android Open Source Project * @@ -6,18 +5,24 @@ * found in the LICENSE file. */ - #ifndef SkTypeface_DEFINED #define SkTypeface_DEFINED -#include "SkAdvancedTypefaceMetrics.h" -#include "SkWeakRefCnt.h" +#include "../private/SkBitmaskEnum.h" +#include "../private/SkOnce.h" +#include "../private/SkWeakRefCnt.h" +#include "SkFontStyle.h" +#include "SkRect.h" +#include "SkString.h" class SkDescriptor; +class SkFontData; class SkFontDescriptor; class SkScalerContext; struct SkScalerContextRec; +struct SkScalerContextEffects; class SkStream; +class SkStreamAsset; class SkAdvancedTypefaceMetrics; class SkWStream; @@ -36,8 +41,6 @@ typedef uint32_t SkFontTableTag; */ class SK_API SkTypeface : public SkWeakRefCnt { public: - SK_DECLARE_INST_COUNT(SkTypeface) - /** Style specifies the intrinsic style attributes of a given typeface */ enum Style { @@ -49,17 +52,25 @@ class SK_API SkTypeface : public SkWeakRefCnt { kBoldItalic = 0x03 }; - /** Returns the typeface's intrinsic style attributes - */ - Style style() const { return fStyle; } + /** Returns the typeface's intrinsic style attributes. */ + SkFontStyle fontStyle() const { + return fStyle; + } - /** Returns true if getStyle() has the kBold bit set. - */ - bool isBold() const { return (fStyle & kBold) != 0; } + /** Returns the typeface's intrinsic style attributes. + * @deprecated use fontStyle() instead. + */ + Style style() const { + return static_cast