当前位置: 首页 > 编程日记 > 正文

chrome 硬件渲染(GPU Accelerated Compositing in Chrome)

原文链接

http://www.chromium.org/developers/design-documents/gpu-accelerated-compositing-in-chrome

chrome 中集成了webkit,这篇文章对webkit 硬件渲染过程有详细的介绍,很好。

简介
这篇文档讲解chrome硬件加速合成的实现细节和背景。

介绍
通常来讲,网页浏览器完全依赖CPU来渲染网页内容。
随着高性能的GPU日益成为设备(即使是最小的设备)的一部分,以及富媒体(video,3D图形游戏)在网络体验中扮演着越来越重要的角色,
人们的注意力开始转向寻找一些方法来更充分利用底层硬件的能力,以提供更好的体验以及更少的电量消耗。
很明显,如果使GPU直接参与网页内容的合成会带来非常显著地提速。这样做最大的好处是可以省去不必要的大量数据拷贝过程,尤其是将内存中的video数据拷贝到系统内存的过程。
这种加速有两个最明显的用武之地,一个是使用硬件解码的Video元素,一个是WebGL canvas, 这两个元素都把它们的结果数据放在一个GPU无法快速访问的内存区域。
将包含网页内容的各个layer的合成交给GPU来做还有另外一些好处。
就涉及大量像素处理的绘制和合成操作而言,GPU要远比CPU有效率(不管是速度还是绘制能力),这是因为针对这些类型的工作负载,GPU有做专门的设计。
将这些操作交给GPU完成,可以实现GPU和CPU并行运行,从而创造出一个高效率的图形处理管线。
第一部分:webkit 渲染基础及软件渲染路径
webkit 渲染引擎的源码非常的繁杂,而且注释和说明性文档实在是太少了。
为了了解GPU加速在Chrome中是怎么工作的,必须先了解webkit 实现页面渲染的基础组件。
我们先简要回顾一下GPU加入以前的工作流程,再分析GPU加入后的工作流程,以此来理解GPU是怎样起作用的。
Nodes and DOM tree
网页内容在webkit 内部以Node为节点的树形结构存储,称为DOM tree。
网页中的每一个HTML 元素,包括元素之间的text都和一个Node相关联。
DOM tree的最顶层Node 永远是Document Node.
Frome Nodes to RenderObjects
Dom tree中每一个可视化的Node 节点都对应着一个RenderObject.RenderObject 也存储在一棵对应的树结构中,称为Render tree.
RenderObject 知道如何在一个display surface上显示(绘制) Node 节点的内容。
它通过调用GraphicsContext提供的绘制接口来完成显示(绘制)过程。
GraphicsContext最终负责将像素写入一块bitmap,这块bitmap会被显示在屏幕上。
在Chrome中,GraphicsContext 封装了Skia, 2D图形库,对GraphicsContext的大多数调用都转变成对SkCanvas或SkPlatformCanvas的接口调用。
在软件渲染的情况下,整个网页只有一个GraphicsContext,所有的RenderObjects都绘制在同一个GraphicsContext上.
From  RenderObjects to RenderLayers
每一个RenderObject 都关联着一个RenderLayer.这种关联是通过祖先RenderObject 节点直接或间接地建立的。
分享同一坐标系的RenderObject(比如被同一CSS transform属性影响的元素)必然位于同一RenderLayer.
正是由于RenderLayer的存在,网页上的元素才可以按照正确的顺序合成,从而恰当的显示有交叠的内容,和半透明元素等效果。
像在RenderBoxModelObject::requiresLayer() 及RenderBoxModelObject的子类中重实现的requiresLayer()中定义的那样,有很多种条件可以
触发一个特定的RenderObject创建一个RenderLayer.
通常来讲,满足下列条件之一时,RenderObject就会创建RenderLayer:
1.网页的root节点;
2.有明确的CSS position属性(relative,absolute,transform)
3.元素是透明的
4.overflow, alpha mask,或者reflection
5.有css filter(滤镜) 属性
6.有2D加速Context或者3D(webGL)context的 canvas 元素对应的RenderObject.
7.video元素对应的RenderObject
需要注意的是RenderObject和RenderLayer之间并不是一一对应的。 
RenderObject 或者与它所创建的RenderLayer相关联(如果它创建了的话),或者与它的第一个拥有RenderLayer的祖先RenderObject创建的RenderLayer相关联。
RenderLayer 也会形成一个树型层次结构。这个树结构的根节点是与网页的根元素相对应的RenderLayer.每一个RenderLayer 节点的后代都是
包含在父亲RenderLayer内的可视化的RenderLayer.
每一个RenderLayer的子节点都被存储在两个按升序排列的有序表中。
negZOrderList 有序表中存储的子节点是z-index值为负的子RenderLayer,所以这些RenderLayer在当前RenderLayer的下面;
posZOrderList有序表中存储的子节点是z-index值为正的子RenderLayer,所以这些RenderLayer在当前RenderLayer的上面;
Putting it Together: many trees
简言之,在概念上存在着三颗平行的树结构,分别负责渲染过程中的不同目的:
DOM Tree 是我们的基础模型;
RenderObject Tree是由DOM Tree的可视化节点一对一映射而来的,RenderObject知道如何渲染它所对应的Dom Node.
RenderLayer Tree 由RenderObject 映射的RenderLayers组成。这种映射关系是多对一的,因为每一个RenderObject或者与它所拥有(创建)的RenderLayer相关联,
或者与它的第一个拥有RenderLayer的祖先RenderObject的RenderLayer相关联。
RenderLayer Tree负责维护RenderLayers 之间的Z-ordering 顺序。

图 render trees.png



the software rendering path
从根本上说,webkit 通过从根节点开始遍历RenderLayer树结构来渲染页面。
Webkit 代码库中包含两种完全不同的渲染路径。软件渲染路径和硬件加速渲染路径。
软件渲染路径是传统的渲染方式。
在软件渲染方式下,按照从后向前顺序绘制各层RenderLayer来渲染页面
从根节点开始递归遍历RenderLayer层次结构。遍历过程中要完成大量工作。
这些工作是在RenderLayer::paintLayer()中完成的,包括以下一些基本步骤(为了更明晰,简要列在这里):
a.判断当前RenderLayer是否与damage rect 有交集;
b.调用paintLayer()递归绘制有序表negZOrderList中的各层RenderLayer;
c.请求与当前RenderLayer相关联的那些RenderObject 绘制它们自己;
d.这个绘制过程是通过遍历以创建当前RenderLayer的RenderObject为开始节点的Render Tree进行的。当遇到一个RenderObject所关联的RenderLayer与当前RenderLayer不同时,遍历过程便结束了。
e.调用paintLayer()递归绘制有序表posZOrderList中的各层RenderLayer;
在软件渲染方式下,RenderObjects 调用一个共享的GraphicsContext(Chrome中是Skia)提供的绘制接口将自己绘制到一块目标bitmap上。
注意,GraphicsContext 本身并没有Layers概念,但是为了正确绘制半透明的RenderLayer.
这里有一个警告:半透明的层在绘制与它自身相关联的RenderObject之前会先调用 GraphicsContext::beginTransparencyLayer()。
在Skia的实现中,beginTransparencyLayer()这个调用会使接下来的所有的绘制命令都绘在一块单独的Bitmap上。
当前RenderLayer绘制完成后,这块单独的Bitmap会和之前的那块Bitmap合成。当与当前的半透明的RenderLayer相关联的RenderObject都绘制完时候,需要相应的调用GraphicsContext::endTransparencyLayer()。
From WebKit to the Screen
图:software rendering architecture


当所有的RenderLayer都绘制到一块共享的Bitmap上后,就需要将这块Bitmap显示到屏幕上。
在Chrome中,这块Bitmap位于一块共享内存中,对这块Bitmap的控制通过IPC方式交给Browser进程。
Browser进程负责调用系统的窗口API将这块Bitmap绘制到合适的窗口中。
第二部分: 硬件基础
回忆Webkit 代码库中包含两种渲染路径,一种是软件渲染路径,一种是硬件加速渲染路径。
如果你已经了解了软件渲染方式,我们可以开始分析硬件加速渲染方式与软件渲染方式的区别。
正如名字所提示的,硬件加速方式就是利用GPU在合成一些RenderLayer的内容时的加速功能。
硬件加速的相关代码由编译时的宏开关ACCELERATED_COMPOSITING 控制。
当至少有一个RenderLayer要求使用硬件加速时,或者当标志 --forced-compositing-mode打开时, 
Chrome就会使用硬件加速渲染路径。这个标志在android和ChromeOS的Chrome中默认都是打开的。
苹果和大多数iOS上的Safari都采用硬件加速的渲染方式,并且大量运用了苹果的CoreAnimation API.
Introducing the compositor
在硬件加速渲染方式下,一些RenderLayer(不是所有)拥有自己的backing surface(拥有单独的backing surface的renderlayer叫做compositing layers).
拥有Backing surface的RenderLayer在绘制时将它们自身绘制到自己的backing surface上,而不是网页公共的那块bitmap上。
随后的合成过程会将所有的backing surface合成到目标Bitmap上。
我们仍然是从RenderLayer Tree开始,以一块单独的Bitmap结束,但是这种分成两个阶段的方式,允许合成器在per-compositing-layer的基础上做一些额外的工作。
例如,在合成每个compositing layer之前,合成器负责对这个compositing layer所对应的bitmap做一些必要的变换(由css 的 transform 属性值指定)。
而且,由于这些Layer的绘制和合成分开了,这些Layer中的一个如果失效,只会引起这一个Layer中内容的重绘,然后再将这个layer重新合成即可。
相反地,在软件渲染中,如果任何一个Layer的内容失效会引起在它上面和下面的所有Layer的重绘。这些都是CPU的不必要的负担。
More Trees: From RenderLayers to GraphicsLayers
在软件渲染方式下,整个网页只有一个GraphicsContext。
在硬件加速合成的方式下,每个compositing layer 都需要一个单独的GraphicsContext,以便每个Compositing layer 都可以绘制在自己单独的
bitmap上。
前面已经讲过,有一组平行的概念上的树结构,每一个都比前一个更稀疏,而且每一个都对前一个的一个子树负责,这组树结依次为:DOM Tree;RenderObject Tree,和RenderLayer Tree.
在介绍硬件合成时,我们要再加一个概念上的树: GraphicsLayer tree。每一个RenderTree或者拥有自己的GraphicsLayer(如果这个RenderLayer是compositing Layer的话),或者是使用它的第一个拥有GraphicsLayer的祖先节点的GraphicsLayer.
RenderLayer与GraphicsLayer的关系类似于RenderObject与RenderLayer之间的关系。每个GraphicsLayer都拥有一个GraphicsContext,与这个GraphicsLayer相对应的每个RenderLayer都绘制到这个GraphicsContext.上。
理论上讲,每一个RenderLayer都可以将自己绘制到一个单独的backing surface上以避免不必要的重绘。
但是在实际中,这种做法会导致内存的大量浪费。在当前的Webkit 实现中,只有满足以下条件之一,RenderLayer才会拥有它自己的composingLayers.(见RenderLayerCompositor::requiresCompositingLayer()):
layer 有3D或者CSS transform 属性值;
layer是硬解码的video 元素使用的;
layer是拥有3D context或2D加速context的Canvas标签使用的;
layer是一个合成的插件使用的;
layer使用了动画表示它的透明度,或者Layer使用了动画形式的webkit 变换;
layer 使用了加速的CSS 滤镜;
拥有compositing layer后代的layer
渲染在Compositing layer之上的layer
这意味着拥有需要合成的RenderLayer的网页总是通过合成器来渲染。其他网页可能需要也可能不需要合成器来渲染,这取决于标志 --forced-compositing- mode 的状态。
the code 
与合成器相关的代码在WebCore中。由USE(ACCELERATED_COMPOSITING)控制。一部分代码是所有平台共享的,一部分是Chrome平台专用的。
webkit的代码结构允许把chrome平台相关的合成器的实现放在平台相关的源文件中(platform/graphics/chromium),不需要修改webkit的核心代码。
同样的,依据Skia图形库实现的GraphicsContext我们也放在了平台相关的源文件中。
GPU 在哪?
GPU是怎样发挥作用的?为了节省耗时的内存传送,加入了加速的合成器。浏览器的Tab区域的最终渲染都由GPU直接控制。
这种模式与当前的render进程将一块含有网页内容的Bitmap通过IPC和共享内存传给浏览器进程去显示的模式是很不相同的。
在含有硬件加速的架构中,硬件加速Layer(比如,需要合成的 Layer,即那些拥有backing surface的Layer)和网页其余内容的合成过程是通过调用平台相关的3D API在GPU上完成的。
实现这些API的最终代码被封装成一个库,这个库运行在渲染进程中,叫做合成器。
合成器库利用GPU合成网页上的矩形区域(例如所有的compositing layers)到一块单独的bitmap中。这块bitmap中的内容就是最终要显示的网页内容。
架构插曲: GPU 进程
在我们进一步分析合成器生成的GPU 命令之前,有必要先了解一下Render进程是怎样向GPU发送命令的。
在chrome平台的多进程模型中,我们有一个专门的进程负责这项工作:GPU进程。GPU进程的存在主要是出于安全方面的考虑。
受限于沙箱性质,渲染进程(webkit 与合成器都运行在此进程)不能直接调用OS提供的3D API(windows平台是Direct3D,其余平台是OpenGL).
出于这个原因,我们需要一个单独的进程做渲染工作。这个进程就是GPU.GPU进程是专门用来访问系统的3D API.它以client-server模式工作:
客户端(运行渲染进程的代码),并不直接调用系统的3D API,而是将这些命令序列化后放在一个环形Buffer(命令Buffer)中,这块环形Buffer位于client进程与server进程之间的一块共享内存中。
服务端(GPU进程,运行在一个可以直接访问平台的3D API的受限较少的砂箱中)将序列化的命令从共享内存中取出,解析,然后调用合适的
图形命令,结果数据直接输出给窗口。

图 GPU Process


GPU 进程接收到的命令的样式类似于GL ES 2.0 API(比如一个命令对应于glClear,一个命令对应于glDrawArrays).由于大部分GL 命令都没有返回值,
所以client 和server之间可以近乎异步的工作。这使性能负载可以保持在非常低的程度。
客户端和服务端的所有同步,比如客户端需要通知服务端有额外的工作需要做,都由IPC机制来控制。
还有一点需要注意的是,共享内存除了存储命令外,还用来在客户和服务器之间传送更大的源数据,比如bitmap for textures,vertext

这里略掉一部分没有翻译
第三部分:硬件渲染模式下,利用合成器渲染
合成器的实现建立在GL ES 2.0的客户端库之上,这个库将图形接口调用代理给GPU 进程(用上文解释的方式)。
当一个网页使用合成器渲染时,它的所有像素都是通过GPU 进程直接绘制到窗口上。
合成器维护着GraphicsLayers的一个层次结构,这个层次结构是通过遍历RenderLayer Tree以及随着页面变化的更新建立的。
除了WebGL和Video Layers,每一个GraphicsLayer的内容都是先绘制到一块系统内存的Bitmap上的(与软件渲染方式中的过程相同):
每一个RenderLayer都请求与它相关联的RenderObject 绘制自身到与当前RenderLayer相关联的GraphicsLayer的GraphicsContext上,即绘制在了
这个GraphicContext相关联位于系统共享内存中的一块Bitmap上。这块Bitmap随后会传给GPU 进程(利用GPU进程一节中介绍的资源传送机制),
接下来,GPU 进程就把这块Bitmap作为一个textue上传给GPU.
合成器跟踪从最近一次被绘制后有变化的GraphicsLayer,只更新与变化的GraphicsLayer相对于的texture.
当所有的texture都上传给GPU之后,渲染页面内容就变成了深度优先遍历GraphicsLayer层次结构并发送GL 命令为之前上传以texture上传给GPU的GraphicsLayer 绘制texture quad.
A texture quad 是屏幕上的用给定的Texture填充的四边形(在我们的例子里,就是GraphicsLayer的内容)。
需要注意的是,深度优先遍历需要确保GraphicsLayer的正确的z-ordering顺序。与每一个GraphicsLayer相关联的RenderLayer的Z-ordering序是在较早的时候RenderObject被光栅化到texture中时予以保证的。
图: compositing with the gpu process

the code 
chrome 平台的合成器代码的实现在webcore下的目录 platform/graphics/chromium中。
合成器的逻辑大部分在LayerRendererChromium.cpp文件中。
各种composited layer的实现分别在文件 {Content|Video|Image} LayerChromium.cpp中。
第四部分:优化!平滑渲染
现在我们已经大致知道怎样用合成器渲染一个页面:网页内容被分布在各个Layerzhong ,Layer被光栅化到textures中,textures被上传给GPU.
合成器告诉GPU将所有的textures合成为最终的屏幕图像。
接下来理解怎么在一秒钟内做60次这些事情,以确保动画,滚动,以及其他的页面交互能平滑进行。
为了解释这些,我们需要介绍与渲染技术的优化相关的一些概念。
Damage:
目前为止,我们只介绍了如何渲染整个页面。这只是Webkit在页面加载完后第一次渲染页面时做的事情。
但是,更典型的情况是,用户与页面交互时只有部分页面内容发生了变化,这时就需要进入damage rect.
当网页内容的可视化部分发生变化时(比如 js 改变了css style,css 动画在运行,或者用户滚动了viewport),webkit 会跟踪网页中需要更新
的部分。跟踪的结果是用一个damage rectangle 记录需要重绘的网页区域。
当绘制时,我们遍历RenderLayer只绘制与damage rectangle 有交集的Layer,跳过与damage rectangle完全没有重叠的Layers.
这就避免了网页中任何一部分变化时都需要重绘整个网页,明显会优化性能。


相关文章:

CCS Font 知识整理总结

总是搞不懂 CCS 中如何正确的使用字体,这下明白了。 1、什么是 font-face font-face 顾名思义,就是文字的脸。字体是文字的外在形式,就是文字的风格,是文字的外衣。比如行书、楷书、草书,都是一种字体。同样一个字每个…

Maven安装与配置(最实用!!!)eclipse中配置maven

Maven安装与配置 一、需要准备的东西 JDKEclipse(本章主要是在eclipse中进行配置maven)Maven程序包 二、下载与安装 1. 前往maven下载最新版的Maven程序: 2. 将文件解压到D:\Program Files\Apache\maven目录下(这样子放目录结…

在Ubuntu 12.04 64bit上配置,安装和运行go程序

注意:下面的安装配置均遵从官网或是教材《Go语言程序设计》中的部分内容. 顺便说下,这是一本很难得的Go语言的入门教程,非常基础和全面。起初我因为这本书的封面比较讨厌它,闲置几年之后,一次偶尔要用时静心翻阅之后,发…

Linux下三个密码生成工具

http://code.csdn.net/news/2820879 想出一个难破解且容易记的密码对不是一件简单的事情。在我为电脑设定一个新密码,或者在线注册了一个新的账号,需要输入密码的时候,脑袋就一片空白。不过,Linux下有几个密码生成工具可以使用&am…

javabean实体类与实体类之间的快速转换

一、Dozer是什么? dozer是一个能把实体和实体之间进行转换的工具.只要建立好映射关系.就像是ORM的数据库和实体映射一样. 使用方法示例如下: // article(PO) -> articleVOArticleVO articleVO dozerMapper.map(article, ArticleVO.class);这段示例代码。将从数…

ATS程序功能和使用方法详解

转载自https://blog.zymlinux.net/index.php/archives/374 Apache Traffic Server的程序文件,与传统的服务器系统有大不同,这里我们将会对这些文件进行详细的解读,并尽可能的对程序的功能和基本用法、参数等进一步说明,以利于新入…

java 读取txt,java读取大文件

java 读取txt,java读取大文件 package com.bbcmart.util; import java.io.File;import java.io.RandomAccessFile;import java.nio.MappedByteBuffer;import java.nio.channels.FileChannel; public class Test { public static void main(String[] args) throws Exception …

Spring Boot整合Spring Data JPA操作数据

一、 Sping Data JPA 简介 Spring Data JPA 是 Spring 基于 ORM 框架、JPA 规范的基础上封装的一套 JPA 应用框架,底层使用了 Hibernate 的 JPA 技术实现,可使开发者用极简的代码即可实现对数据的访问和操作。它提供了包括增删改查等在内的常用功能&…

常用Linux命令总结

常用Linux命令总结 2013-12-08 压缩为gz格式 gzip error_2018082217.log 解压gz格式 gzip -d error_2018082217.log.gz 不解压来搜索gz格式的文件中的匹配行内容 gunzip -c 不真正解压.gz文件,而是检查该文件,不会生成多余的文件 gunzip -c error_20…

调试uIP出现死机问题

在调试uIP,加入http功能时,调试出现死循环 原因是所加入的http文件中含有printf等输出函数,遇到这种情况,有2种解决方法: 1.Keil中勾选“Use MicroLIB” 2. //加入以下代码,支持printf函数,而…

html+spring boot简单的ajax数据传输实现

本篇讲解在前后端不分离情况下的htmlspring boot的项目数据传输实现 首先,后台我写了三个接口 package com.demo.ajax.controller;import com.demo.ajax.Entity.Person; import lombok.extern.slf4j.Slf4j; import org.jboss.logging.Param; import org.springfram…

Tafficserver旁路接入方案综述

转载自 https://blog.zymlinux.net/index.php/archives/821 随着宽带技术的加速普及,目前,几款高性能开源CDN方案在广大开源爱好团队的充分的测试、企业服务应用验证中破壳而出。实际这个地球的互联网用户都在知情与不知情之间使用了ATS的环保服务。这方…

url中去掉index.php,方便redirect()

01 配置文件 return Array( URL_MODEL > 2,); 02 index.php入口文件下面加入文件 .htaccess -->使用editplus-->另存为 <IfModule mod_rewrite.c>RewriteEngine onRewriteCond %{REQUEST_FILENAME} !-dRewriteCond %{REQUEST_FILENAME} !-fRewriteRule ^(.*)$ i…

js校验复选框(多选按钮)是否被选中的方法

js校验复选框是否被选中的方法 方法一&#xff1a;&#xff08;使用下标进行标记&#xff09; if ($("#checkbox-id")get(0).checked) {// do something }方法二&#xff1a;&#xff08;对被选中的进行操作&#xff09; if($(#checkbox-id).is(:checked)) {// do…

ATS插件开发基础

转载自 https://blog.zymlinux.net/index.php/archives/540 ATS插件开发需要提前了解ATS的插件的一些设计思想&#xff0c;以及系统提供的一些不同方向。我们将会介绍ATS的基础开发知识&#xff0c;以利于后续的插件开发课程讲解。 ATS的SDK文档&#xff0c;是了解ATS的核心设…

NET基础(3):is 和 as 操作符

在C#语言中进行类型转换的另外一种方式是使用is和as操作符。is检查对象是否兼容于指定类型&#xff0c;返回Boolean值true或false。注意&#xff0c;is操作符永远不抛出异常&#xff0c;例如以下代码&#xff1a; Object o new Object();Boolean b1 (o is Object); //返回…

制作大白菜PE盘

大白菜是一款功能非常强大的U盘启动盘制作工具&#xff0c;通过大白菜我们可以把U盘做成可以引导电脑启动的启动盘&#xff0c;同时可以用于装系统或维护系统&#xff0c;虽然制作方法非常简单&#xff0c;不过还是有很多人不懂如何制作大白菜U盘启动盘&#xff0c;这两天我刚好…

为方便ATS管理建立的一些命令别名

转载自https://blog.zymlinux.net/index.php/archives/129 玩ats经常需要切换目录什么感觉敲得麻烦了就建立了一些命令别名&#xff0c;就方便多了。 在用户目录下的.bashrc文件中加入以下内容&#xff1a; alias alogcd /usr/local/var/log/trafficserver;pwd alias atscd /us…

short s1 = 1; s1 = s1 + 1;有错而short s1 = 1; s1 += 1正确

这个问题以前碰到过&#xff0c;也研究过&#xff0c;发表一下&#xff1a; 如果你认为表达式&#xff08;x i&#xff09;只是表达式&#xff08;x x i&#xff09;的简写方式&#xff0c;这并不准确。这两个表达式都被称为赋值表达式。第二个表达式使用的是简单赋值操作…

pom文件中引入常用的maven仓库

给大家分享几个maven仓库&#xff0c;如果本地总是下载很慢的话可以尝试换一下仓库或者多加几个。可以直接拖放在pom.xml中使用。 阿里云仓库 <mirrors><mirror><id>alimaven</id><name>aliyun maven</name><url>http://maven.ali…

ats新手学习参考

转载自https://blog.zymlinux.net/index.php/archives/129 首先申明本人是个实实在在的菜鸟&#xff0c;现在也只是搭建起来ats玩玩简单的&#xff0c;写本文只是为了给完全的小白一个参考而已。 本人刚开始接触ats的时候&#xff0c;从ats安装到配置也遇到了很多基本的问题&am…

[svc]磁盘接口与RAID

一 磁盘接口 IDE 传统家用: /dev/hda1 SISC 传统服务器: /dev/sdb1 SATA 现在家用 SAS 现在服务器用 FC(光纤通道) 高级服务器 注意: 分区编号,1-4只能给主分区或扩展分区使用,逻辑分区是基于扩展分区来搞的,编号从5开始. MBR分区参考 现在计算机性能瓶颈往往在硬盘: …

条形码?二维码?生成、解析都在这里!

二维码生成与解析 一、生成二维码 二、解析二维码 三、生成一维码 四、全部的代码 五、pom依赖 直接上代码&#xff1a; 一、生成二维码 public class demo {private static final String path1"D:\\code.jpg";private static void qr(String text,int width,int w…

异步预热在线视频实现

转载自https://blog.zymlinux.net/index.php/archives/100 毕业之际给学校搭建了基于ATS的正向代理缓存服务器&#xff0c;专门用来处理优酷土豆等在线视频流量。通过改写一个浏览器做成在线视频专用浏览器&#xff0c;内置了ATS的代理设置。 用php配合memcacheq和小脚本实现了…

文本输入框、密码输入框

当用户要在表单中键入字母、数字等内容时&#xff0c;就会用到文本输入框。文本框也可以转化为密码输入框。 语法&#xff1a; <form><input type"text/password" name"名称" value"文本" /> </form> 1、type&#xff1a; 当t…

Linux安装mysql,一步到位!

今天在腾讯云上面买了一个服务器&#xff0c;想要把自己的项目部署一下&#xff0c;就要安装mysql&#xff0c;以下是我的安装步骤,在网上有很多人把install敲错了&#xff0c;还有的少-get&#xff0c;种种错误试完之后&#xff0c;我决定发一篇 sudo apt-get install mysql-…

Ubuntu 12.04安装firefox 26中的flash plugin方法

Ubuntu 12.04 64bit中安装firefox 26中的flash player插件的方法昨天, 有最新的firefox 26更新了,可是我在软件更新中无法下载到ubuntu官方源中的flash plugin,详细的情况可以参见如下网页,这个问题我一年前也遇到过,特记录下来,以备后来查阅.http://blog.sina.com.cn/s/blog_9…

内联式css样式,直接写在现有的HTML标签中

CSS样式可以写在哪些地方呢&#xff1f;从CSS 样式代码插入的形式来看基本可以分为以下3种&#xff1a;内联式、嵌入式和外部式三种。这一小节先来讲解内联式。 内联式css样式表就是把css代码直接写在现有的HTML标签中&#xff0c;如下面代码&#xff1a; <p style"col…

Linux下安装Java8

Linux(ubuntu)下Java8安装 1.下载jdk8 这个看大家了&#xff0c;linux版本的就可以 2.创建jvm文件夹 在根目录下创建名为jvm的文件夹&#xff08;在哪里创建看个人&#xff09; $ sudo mkdir jvm3.将下载的包解压到jvm文件夹下 $ sudo tar zxvf 压缩包路径/名字 -C /jvm…

RTMFP协议

RTMFP是Adobe公司开发的一套新的通信协议&#xff0c;该协议可以让使用Adobe Flash Player的终端用户之间进行直接通信。用Adobe AIR框架开发的程序也可以用此协议来发布直播、实时信息。  通过使用RTMFP, 那些原来直播、实时通信的应用&#xff0c;比如社区、音视频聊天和多人…