skia研究文档.docx
- 文档编号:27942293
- 上传时间:2023-07-06
- 格式:DOCX
- 页数:237
- 大小:460.58KB
skia研究文档.docx
《skia研究文档.docx》由会员分享,可在线阅读,更多相关《skia研究文档.docx(237页珍藏版)》请在冰豆网上搜索。
skia研究文档
第一节:
skia介绍
Google的 Android 系统底层使用了skia作为其核心图形引擎,Google的Chrome亦是使用skia作为图形引擎。
Skia图形渲染引擎最初由Skia公司开发,该公司于2005年被Google收购。
Skia是一款非常优秀的向量显示引擎,能在低端设备(如手机、电视和其他手持设备等)上呈现高质量的2D图形,设置可以搭配OpenGL/ES与特定的硬件特效,强化显示效果。
Skia是C++代码编写的,它具有以下一些特点:
⏹高度优化的rasteriser->Optimisedsoftware-basedrasteriser(modulesgl/);
⏹选择性透过OpenGL/ES,加速特定操作,如shader和textures-> OptionalGL-basedaccelerationofcertaingraphicsoperationsincludingshadersupportandtextures(modulegl/);
⏹动画处理能力->Animationcapabilities(moduleanimator/);
⏹内建SVG支持->Somebuilt-inSVGsupport(module(svg/)
⏹內建若干imagecodec,如PNG,JPEG,GIF,BMP(modulesimages/)->Built-inimagedecoders:
PNG,JPEG,GIF,BMP,WBMP,ICO(modulesimages/);
⏹内建文字处理,但缺乏泰文、藏文等复杂文字处理能力->Textcapabilities(nobuilt-insupportforcomplexscripts);
⏹UI界面套件->Someawarenessofhigher-levelUItoolkitconstructs(platformwindows,platformevents):
Mac,Unix(sic.X11,incomplete),Windows,wxwidgets
Skia的功能特性包括:
⏹Copy-on-writeforimagesandcertainotherdatatypes;
⏹Extensiveuseofthestack,bothinternallyandforAPIconsumerstoavoidneedlessallocationsandmemoryfragmentation;
⏹线程安全,支持并行执行->Thread-safetytoenableparallelisation.
Skia源码的目录结构是非常清晰的:
1:
animator目录
顾名思意,这部分是用来实现Skia的动画效果。
主要包含79个CPP文件。
从文件名来看,主要分为以下几类:
以SkAnimator开头的一些文件,SkAnimatorActive,SkAnimatorBase,SkAnimatorField,SkAnimatorSet,SkAnimatorScript等。
以SkDisplay开头的一些文件,SkDisplayAdle,SkDisplayAdd,SkDisplayEvents,SkDisplayList,SkDisplayInput,SkDisplayMovie等。
以SkDraw开头的一些文件,SkDraw3D,SkDrawBitmap,SkDrawClip,SkDrawColor,SkDrawBlur,SkDrawLine,SkDrawPaint,SkDrawPath,SkDrawPoint等。
以SkScript开头的一些文件,包括SkScript,SkScriptRuntime,SkScriptDecompile等。
2:
core目录
这就是skia的核心了,主要包含89个CPP文件。
基本都是一些图形绘制函数。
主要包括SkColor,SkCanvas,SkBitmap,SkPicture,SkBlitter,SkCordic,SkPath,SkPoint,SkRect,SkRegion,SkMask等图形绘制类,还包括一些辅助性的类文件,sk64,skbuffer,skutils等。
3:
effects目录
这是skia实现一些图形图像效果的部分。
主要包括20个CPP文件。
主要实现了以下特效:
遮罩、浮雕、模糊、滤镜、渐变色、离散、透明等。
并且实现了PATH的各种特效。
4:
gl目录
这是用来调用opengl实现部分效果。
主要包括7个CPP文件。
开打SkGL.h,可以发现
#ifdefSK_BUILD_FOR_MAC
#include
#include
#include
//useFBOsfordevices
#defineSK_GL_DEVICE_FBO
#elifdefined(ANDROID)
#include
#include
#endif
所以,这部分是skia调用OpenGL或OpenGLES来实现3D效果。
如果定义了MAC,则使用OpenGL,如果定义了Android,则使用嵌入式系统 上的esgl三维图形库。
porting的时候要加上#elifdefined(SYMBIAN)之类的,防止别的地方也有android宏定义。
打开SkGL,发现是几个基本的材质贴图函数。
5:
images目录
这部分是用来处理images的,共23个CPP文件和一些头文件。
主要是SkImageDecoder和SkImageEncoder以及SkMovie。
Skia能处理的图像类型包括以下
BMP
JPEG/PVJPEG
PNG
ICO
另外,skia还能处理PDF文档。
使用了一个fpdfemb库。
而SkMovie就是处理gif动画。
6:
ports目录
这部分是skia的一些接口在不同系统上的实现,共24个CPP文件。
主要包括几个部分:
Font,Event,File,Thread,Time,XMLParser
这些与Skia的接口,需要针对不同的操作系统 实现。
7:
svg目录
这个目录包含28个CPP文件,从文件名看,都是一些画图文件。
SkSVGPath,SkSVGPolyline,SkSVGRect,SkSVGText,SkSVGLine,SkSVGImage,SkSVGEllipse等等。
8:
utils目录
包含9个CPP文件,是一些辅助工具类。
SkCamera,SkColorMatrix,SkOSFile,SkProxyCanvas,SkInterpolator等文件
9:
views目录
这个目录包含24个CPP文件。
skia构建了一套界面UI库。
组件包括Window,Menu,TextBox,ListView,ProgressBar,Widget,ScrollBar,TagList,Image等。
还有组件的事件类。
window对象负责接收事件,并传递给当前focus对象,若无focus对象,则focus自身。
focus对象处理相应的keyevents和mouseevents。
在SkiView基类类中定义并实现了draw,acceptFocus,moveFocus,click等方法。
10:
xml目录
当然,这是处理xml数据的部分了。
skia在这里只是对xml解析器做了一层包装,具体的xml解析器的实现需要根据不同的操作系统及宿主程序来实现。
第二节:
skia的基本图形绘制
Skia的基本绘图功能包括点、直线、矩形、椭圆、图像以及矢量路径。
为了更好的控制这些图形图像的绘制,skia支持多种裁减区、蒙版及滤镜。
1:
SkShader
/**\classSkShader
SkShader是基础类,派生那些在绘图时用于获取水平方向颜色值的对象类。
SkShader的子类用在paint.setShader(shader),之后任何用该paint进行的绘图都将使用源自shader的颜色。
SkBitmapProcShader、SkColorShader、SkFilterShader、SkComposeShader均从此类派生。
*/
classSkShader:
publicSkFlattenable{
public:
SkShader();
virtual~SkShader();
/**如果shader的本地矩阵是非单位矩阵,则返回真
@paramlocalM可选参数,非空,则返回本地矩阵
@非单位矩阵,则返回真,否则为假
*/
boolgetLocalMatrix(SkMatrix*localM)const;
/**设置本地矩阵
@paramlocalM新的本地矩阵
*/
voidsetLocalMatrix(constSkMatrix&localM);
/**重置本地矩阵为单位矩阵
*/
voidresetLocalMatrix();
enumTileMode{
kClamp_TileMode,//超过边界的部分用边界的颜色填充
kRepeat_TileMode,//水平和竖直方向重复
kMirror_TileMode,//水平和竖直方向重复,且以镜面反射方式
kTileModeCount
};
//overridetheseinyoursubclass
enumFlags{
//如果所有颜色都是不透明的,需要设置此项
kOpaqueAlpha_Flag=0x01,
//如果shadeSpan16()方法可以调用,则置此标志
kHasSpan16_Flag=0x02,
/**如果shader的本地数据是16位的,则设置此标志。
设此标志后,对32位的shadeSpan()调用将默认从16位转成32位。
*/
kIntrinsicly16_Flag=0x04,
/**如果span仅在x方向变化,y方向为常量,则设置此标志。
比如,Nx1的位图Y方向需要平铺,从左到右需要线性变化。
本标志用于标识shadeSpan()。
*/
kConstInY32_Flag=0x08,
/**类似于kConstInY32_Flag
*/
kConstInY16_Flag=0x10
};
/**使用本shader绘图之前调用,用于返回shader的透明类型
默认是的实现返回0,为了使用各种blitter提供性能,子类需要重载该函数,以返回正确的值。
*/
virtualuint32_tgetFlags(){return0;}
/**获取与shadeSpan16()返回数据关联的alpha值。
如果kHasSpan16_Flag没有置位,此值无效。
*/
virtualuint8_tgetSpan16Alpha()const{returnfPaintAlpha;}
/**设置画笔和设备矩阵,在绘图之前调用。
如果shader支持输入参数,则返回真,否则为假。
*/
virtualboolsetContext(constSkBitmap&device,constSkPaint&paint,
constSkMatrix&matrix);
/**每个对象绘制之前都需要调用。
子类需要对指定的设备坐标设置合适的颜色(预乘alpha)
*/
virtualvoidshadeSpan(intx,inty,SkPMColor[],intcount)=0;
/**仅用于16位的设备,即仅当getFlags()返回 kOpaqueAlphaFlag|kHasSpan16_Flag
*/
virtualvoidshadeSpan16(intx,inty,uint16_t[],intcount);
/**类似于shadeSpan,但仅返回span的透明通道
默认的实现是调用shadeSpan()并且抽取返回颜色的透明度
*/
virtualvoidshadeSpanAlpha(intx,inty,uint8_talpha[],intcount);
/**帮助型的函数。
用于判断能否调用shadeSpan16()方法
*/
boolcanCallShadeSpan16(){
returnSkShader:
:
CanCallShadeSpan16(this->getFlags());
}
/**检查flags,以查验调用shadeSpan16()是否合法
*/
staticboolCanCallShadeSpan16(uint32_tflags){
return(flags&kHasSpan16_Flag)!
=0;
}
/**在使用shader之前调用,有些shaders重载此方法(比如,调用bitmap.lockPixels())
必须和endSession()匹配使用
*/
virtualvoidbeginSession();
virtualvoidendSession();
/**当与opengl交互时,用于将shader作为位图或纹理。
此法可选择实现,
默认的实现仅返回false,并且忽略输出参数。
*/
virtualboolasABitmap(SkBitmap*outTexture,SkMatrix*outMatrix,
TileModexy[2]);
//////////////////////////////////////////////////////////////////////////
//Factorymethodsforstockshaders
/**创建位图形式的shader
@paramsrcshader内部使用的位图
@paramtmxx方向采样位图时采用的模式
@paramtmyy方向采用位图时采用的模式
@return返回新的shader对象
*/
staticSkShader*CreateBitmapShader(constSkBitmap&src,
TileModetmx,TileModetmy);
virtualvoidflatten(SkFlattenableWriteBuffer&);
protected:
enumMatrixClass{
kLinear_MatrixClass,//无透视视图
kFixedStepInX_MatrixClass,//快速透视,每扫描调用fixedStepInX()
kPerspective_MatrixClass//慢速透视,每像素都需要映射
};
staticMatrixClassComputeMatrixClass(constSkMatrix&);
//在setContext()之后可以调用以下方法
uint8_tgetPaintAlpha()const{returnfPaintAlpha;}
SkBitmap:
:
ConfiggetDeviceConfig()const{return(SkBitmap:
:
Config)fDeviceConfig;}
constSkMatrix&getTotalInverse()const{returnfTotalInverse;}
MatrixClassgetInverseClass()const{return(MatrixClass)fTotalInverseClass;}
SkShader(SkFlattenableReadBuffer&);
private:
SkMatrix*fLocalMatrix;//本地矩阵
SkMatrixfTotalInverse;//矩阵的逆矩阵
uint8_tfPaintAlpha;//绘图的alpha值
uint8_tfDeviceConfig;//设备配置
uint8_tfTotalInverseClass;//逆矩阵的类型
SkDEBUGCODE(SkBool8fInSession;)
/**创建位图形式的shader
*/
staticSkShader*CreateBitmapShader(constSkBitmap&src,
TileMode,TileMode,
void*storage,size_tstorageSize);
friendclassSkAutoBitmapShaderInstall;
typedefSkFlattenableINHERITED;
};
2:
SkRasterizer
/**\SkRasterizer
光栅化操作类。
*/
classSkRasterizer:
publicSkFlattenable{
public:
SkRasterizer(){}
/**将路径转为蒙版,需要由指定的局部坐标系转换到设备坐标系
@parampath 待转换的路径
@parammatrix 局部坐标系
@paramclipBounds裁减区
@parammask蒙版
@mode创建莫斯
@return成功则返回true,否则返回false
*/
boolrasterize(constSkPath&path,constSkMatrix&matrix,
constSkIRect*clipBounds,SkMaskFilter*filter,
SkMask*mask,SkMask:
:
CreateModemode);
virtualvoidflatten(SkFlattenableWriteBuffer&){}
protected:
SkRasterizer(SkFlattenableReadBuffer&);
/**执行光栅化
@parampath 待转换的路径
@parammatrix 局部坐标系
@paramclipBounds裁减区
@parammask蒙版
@mode创建莫斯
@return成功则返回true,否则返回false
*/
virtualboolonRasterize(constSkPath&path,constSkMatrix&matrix,
constSkIRect*clipBounds,
SkMask*mask,SkMask:
:
CreateModemode);
private:
typedefSkFlattenableINHERITED;
};
3:
SkBitmapSampler
/**\SkBitmapSampler
位图采样器。
*/
classSkBitmapSampler{
public:
SkBitmapSampler(constSkBitmap&,boolfilter,SkShader:
:
TileModetmx,SkShader:
:
TileModetmy);
virtual~SkBitmapSampler(){}
/**获取位图元素
*/
constSkBitmap&getBitmap()const{returnfBitmap;}
/**获取处理(采样)后的位图
*/
boolgetFilterBitmap()const{returnfFilterBitmap;}
/**获取x方向的模式
*/
SkShader:
:
TileModegetTileModeX()const{returnfTileModeX;}
/**获取y方向的模式
*/
SkShader:
:
TileModegetTileModeY()const{returnfTileModeY;}
/**返回给定坐标位置[x,y]处的采样颜色
*/
virtualSkPMColorsample(SkFixedx,SkFixedy)const=0;
/**设置绘图对象
*/
virtualvoidsetPaint(constSkPaint&paint);
//这是一个查找最优子类的工厂
/**用给定的规格创建位图采样器
*/
staticSkBitmapSampler*Create(constSkBitmap&,boolfilter,
SkShader:
:
TileModetmx,SkShader:
:
TileModetmy);
protected:
constSkBitmap&fBitmap;//源位图
uint16_tfMaxX,fMaxY;//x和y方向的最大尺寸
boolfFilterBitmap;//处理(采样)后的位图
SkShader:
:
TileModefTileModeX;//x方向处理的模式
SkShader:
:
TileModefTileModeY;//y方向处理的模式
SkTileModeProcfTileProcX;//x方向处理函数
SkTileModeProcfTileProcY;//y方向处理函数
//illegal
SkBitmapSampler&operator=(constSkBitmapSampler&);
};
4:
SkCubicClipper
/**\SkCubicClipper
三次曲线剪切类。
此类需要用裁减矩形来初始化,然后裁减输入的三次曲线,当然次三次曲线必须在Y方向是单调的(单调递增或者单调递减)。
将来,本类将返回一系列的片段,支持X方向的裁减以保证所有的片段都处在有限的坐标系中。
*/
classSkCubicClipper{
public:
SkCubicClipper();
/**设置裁减区
*/
voidsetClip(constSkIRect&clip);
/**裁减三次曲线,如果裁剪后有内容,则返回true,否则返回false。
@paramsrc[4]构成三次曲线的四个点
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- skia 研究 文档