11. Html5的局:从CPU到GPU,底层技术的变化

简介: # 紧接上文 WebGL为不同的平台/硬件提供了统一的封装,屏蔽了OpenGL ES2.0在各平台差异。后续我们会继续谈谈OpenGL ES2.0在Android/iOS平台的更多差异。 这回我们分析WebKit的源码,谈谈WebGL与Cavans不同,WebGL又多做了哪些呢,性能提升在哪里呢。 # 在H5中渲染机制 我们可以使用多种方式来绘制图形【本文以iOS版本的WebKit为例

紧接上文

WebGL为不同的平台/硬件提供了统一的封装,屏蔽了OpenGL ES2.0在各平台差异。后续我们会继续谈谈OpenGL ES2.0在Android/iOS平台的更多差异。
这回我们分析WebKit的源码,谈谈WebGL与Cavans不同,WebGL又多做了哪些呢,性能提升在哪里呢。

在H5中渲染机制

我们可以使用多种方式来绘制图形【本文以iOS版本的WebKit为例】
DOM+CSS:
为前端提供了强大图形渲染技术,门槛低上手快,对硬件要求较高。

Canvas2D:
元素本身并没有绘制能力,它仅仅是2D图形的容器,必须使用脚本来完成实际的绘图任务。getContext('2d') 方法可返回一个对象CanvasRenderingContext(后续简称canvas),该对象提供了用于在画布上绘图的方法和属性,可用于在画布上绘制图片、文本、图形、颜色等,并提供常见的图形转换API,进行图片的缩放、旋转、像素再加工能力,最终通过OpenGL渲染到屏幕上。

Canvas3D:
同2D一样,本身没有渲染能力,通过getContext('webgl')方法可以返回一个基于OpenGL ES2.0上下文的对象WebGLRenderingContext(后续简称webgl),通过webgl可以直接访问GPU硬件资源,对码农要求更高,优化空间更大。

2D领域Canvas VS WebGL

Canvas使用CoreGraphics渲染图像

WebKit的实现代码

context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height);

对应GraphicsContext.cpp中的

void GraphicsContext::drawNativeImage(imagePtr, imageSize, styleColorSpace, destRect, srcRect, op, blendMode, orientation) {
······
    // Flip the coords.
    CGContextTranslateCTM(context, 0, adjustedDestRect.height());
    CGContextScaleCTM(context, 1, -1);

    // Adjust the color space.
    image = Image::imageWithColorSpace(image.get(), styleColorSpace);

    // Draw the image.
    CGContextDrawImage(context, adjustedDestRect, image.get());

    CGContextRestoreGState(context);
······
}

WebGL直接使用OpenGL ES2.0渲染图片:

在《 07. WebApp2.0时代启程:倒立者赢,从CPU到GPU,一张图片的旅行 》中,这里不重新做说明了。

Canvas与WebGL的对比

CoreGraphics是运行在CPU上的图形库

它在iOS中已经深入的融合到UIView和UILayer框架中,架构图如下:
screenshot

WebGL只是对OpenGL ES2.0的轻量级封装

js代码

gl.bindTexture(gl.TEXTURE_2D, texID);

在WebKit中对应于C++代码:

void GraphicsContext3D::bindTexture(GC3Denum target, Platform3DObject texture) {
    makeContextCurrent();
    if (m_state.activeTexture == GL_TEXTURE0 && target == GL_TEXTURE_2D)
        m_state.boundTexture0 = texture;
    ::glBindTexture(target, texture);
}

图形渲染WebGL完胜Canvas

CPU在RAM中处理完图片后,仍需要上传到GPU中才可以显示,同时,GPU图形渲染速度比CPU提升10倍以上。
screenshot

Canvas的不可替代和WebGL的优势

Canvas提供高级的图形渲染API

直接使用DOM对象绘制图形

var canvas = document.getElementById("myCanvas");
var cxt=canvas.getContext("2d");
var img = new Image()
img.src = "flower.png"
cxt.drawImage(img, 0, 0);

而WebGL需要负责的代码实现:

    gl.bindTexture(gl.TEXTURE_2D, texture._glTextures[gl.id]);
    gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultipliedAlpha);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.source);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, texture.scaleMode === CONST.SCALE_MODES.LINEAR ? gl.LINEAR : gl.NEAREST);

可以渲染文字

使用 fillText(),在画布上写文本 "Hello world!" 和 "w3school.com.cn":
screenshot
JS代码为:

var canvas=document.getElementById("myCanvas");
var ctx=canvas.getContext("2d");

ctx.font="20px Georgia";
ctx.fillText("Hello World!",10,50);

ctx.font="30px Verdana";
// 创建渐变
var gradient=ctx.createLinearGradient(0,0,c.width,0);
gradient.addColorStop("0","magenta");
gradient.addColorStop("0.5","blue");
gradient.addColorStop("1.0","red");
// 用渐变填色
ctx.fillStyle=gradient;
ctx.fillText("w3school.com.cn",10,90);

WebGL无此API,WebKit也是通过FreeType通过CPU来实现文字的加载与渲染。如果需要渲染文字,需要生成一个Canvas对象,在Canvas绘制完成之后,在直接渲染到WebGL空间。

高效的上下文切换

多个Canvas实例可以轻松切换,因为在CPU中他只是一个静态的Bitmap。
而WebGL上线文最好只有一个,切换上线文需要更改GPU硬件管线的状态和flushbuffer,频繁的切换会消耗大量的CPU资源。

WebGL的优势

GPU的framebuffer直接push到Display

CPU需要将渲染好的内存Bitmap上传给GPU,然后通过display link到屏幕上。
WebGL避免了CPU到GPU的大量的数据传输,只需要发送指令给GPU即可。

支持批量渲染

支持vertexArray和IndiceArray,多个精灵共享一张文理,只需要将vertext数据缓冲到顶点数据,通过glDrawElements可以一次批量渲染。

支持异步操作

Canvas的API每次都是同步操作,每次渲染必然同步到framebuffer中,不利于性能优化。WebGL可以自定义渲染机制和时机

下一回

我们将谈谈WebGL的纹理格式转换,也是WebGL区别于OpenGL ES2.0最大的区别。

相关实践学习
基于阿里云DeepGPU实例,用AI画唯美国风少女
本实验基于阿里云DeepGPU实例,使用aiacctorch加速stable-diffusion-webui,用AI画唯美国风少女,可提升性能至高至原性能的2.6倍。
目录
相关文章
|
13天前
|
搜索推荐 定位技术 UED
HTML定位技术:种类、特点与应用
HTML定位技术:种类、特点与应用
|
30天前
|
人工智能 并行计算 PyTorch
【PyTorch&TensorBoard实战】GPU与CPU的计算速度对比(附代码)
【PyTorch&TensorBoard实战】GPU与CPU的计算速度对比(附代码)
37 0
|
6天前
|
移动开发 前端开发 JavaScript
《HTML 简易速速上手小册》第8章:HTML 表单高级技术(2024 最新版)
《HTML 简易速速上手小册》第8章:HTML 表单高级技术(2024 最新版)
22 0
|
1月前
|
数据采集 存储 JavaScript
PHP爬虫技术:利用simple_html_dom库分析汽车之家电动车参数
本文旨在介绍如何利用PHP中的simple_html_dom库结合爬虫代理IP技术来高效采集和分析汽车之家网站的电动车参数。通过实际示例和详细说明,读者将了解如何实现数据分析和爬虫技术的结合应用,从而更好地理解和应用相关技术。
PHP爬虫技术:利用simple_html_dom库分析汽车之家电动车参数
|
3月前
|
人工智能 弹性计算 安全
【Hello AI】GPU容器共享技术cGPU
GPU容器共享技术cGPU是阿里云基于内核虚拟GPU隔离的容器共享技术。即多个容器共享一张GPU卡,从而实现业务的安全隔离,提高GPU硬件资源的利用率并降低使用成本。
【Hello AI】GPU容器共享技术cGPU
|
3月前
|
机器学习/深度学习 并行计算 算法
简单理解CPU与GPU的区别
简单理解CPU与GPU的区别
63 0
|
3月前
|
数据采集 安全 JavaScript
​HTML代码混淆技术:原理、应用和实现方法详解
​HTML代码混淆技术:原理、应用和实现方法详解
68 0
|
4月前
|
并行计算 TensorFlow 算法框架/工具
Linux Ubuntu配置CPU与GPU版本tensorflow库的方法
Linux Ubuntu配置CPU与GPU版本tensorflow库的方法
|
4月前
|
机器学习/深度学习 TensorFlow 算法框架/工具
Anaconda配置Python新版本tensorflow库(CPU、GPU通用)的方法
Anaconda配置Python新版本tensorflow库(CPU、GPU通用)的方法
|
4月前
|
并行计算 Linux 计算机视觉
DeepFace【部署 04】轻量级人脸识别和面部属性分析框架deepface使用Docker部署CPU+GPU两个版本及cuDNN安装
DeepFace【部署 04】轻量级人脸识别和面部属性分析框架deepface使用Docker部署CPU+GPU两个版本及cuDNN安装
207 0