概述
- ANativeWindow : opengl工作的绘图画布本地窗口,按标准定义好函数(下面好多代码都简化)
struct
ANativeWindow
{
.....
//上层定义好函数指针,传给opengl后,opengl在必要的时候会调用相应的函数
int
(*
dequeueBuffer
)(
struct
ANativeWindow
*
window
,
struct
ANativeWindowBuffer
**
buffer
,
int
*
fenceFd
);
int
(*
queueBuffer
)(
struct
ANativeWindow
*
window
,
struct
ANativeWindowBuffer
*
buffer
,
int
fenceFd
);
int
(*
cancelBuffer
)(
struct
ANativeWindow
*
window
,
struct
ANativeWindowBuffer
*
buffer
,
int
fenceFd
);
}
ANativeWindowBuffer:绘制的图像缓冲区
struct
ANativeWindowBuffer
{
int
width
;
int
height
;
int
usage
;
.....
//通过这个handle就跟Gralloc模块申请的图片缓存关联起来了,可能在fb申请也能是共享内存中申请的(看他了
usage )
buffer_handle_t
handle
;
}
fenceFd:暂时把他当作这个buffer的锁,因为缓存区需要cpu,gpu,composer共享,普通锁不管用啊。
2.
android中的本地窗口
(1.)操作显存的,surfaceflinger服务中应用的。最总渲染到屏幕的
FramebufferNativeWindow
:
public
ANativeObjectBase
<
ANativeWindow
,
FramebufferNativeWindow
,
LightRefBase
<
FramebufferNativeWindow
> >
别看上面的这么复杂其实就是 FramebufferNativeWindow: public
ANativeWindow,看名字就是包装了fb显存了,用它直接绘制到屏幕上的
构造函数:
FramebufferNativeWindow
::
FramebufferNativeWindow
()
:
BASE
(),
fbDev
(0),
grDev
(0),
mUpdateOnDemand
(
false
)
{
hw_module_t
const
*
module
;
//打开Gralloc硬件抽象层模块
hw_get_module
(
GRALLOC_HARDWARE_MODULE_ID
, &
module
);
//获取抽象层中的fb设备定义,渲染到屏幕的
f
ramebuffer_open
(
module
, &
fbDev
);
//获取抽象层图像缓存申请设备,获取一段内存或显存的
gralloc_open
(
module
, &
grDev
);
//看一下fb支持缓冲区大小,可能有多个离屏缓冲,初始化一下这些缓冲区
if
(
fbDev
->
numFramebuffers
>=
MIN_NUM_FRAME_BUFFERS
&&
fbDev
->
numFramebuffers
<=
MAX_NUM_FRAME_BUFFERS
){
mNumBuffers
=
fbDev
->
numFramebuffers
;
}
else
{
mNumBuffers
=
MIN_NUM_FRAME_BUFFERS
;
}
for
(
i
= 0;
i
<
mNumBuffers
;
i
++)
{
// NativeBuffer
:
public
ANativeWindowBuffer 从ANativeWindowBuffer继承
buffers
[
i
] =
new
NativeBuffer
(
fbDev
->
width
,
fbDev
->
height
,
fbDev
->
format
,
GRALLOC_USAGE_HW_FB
);
grDev
->
alloc
(
grDev
,
fbDev
->
width
,
fbDev
->
height
,
fbDev
->
format
,
GRALLOC_USAGE_HW_FB
, &
buffers
[
i
]->
handle
, &
buffers
[
i
]->
stride
);
}
//opengl需要的本地窗口定义了
const_cast
<
uint32_t
&>(
ANativeWindow
::
flags
) =
fbDev
->
flags
;
const_cast
<
float
&>(
ANativeWindow
::
xdpi
) =
fbDev
->
xdpi
;
const_cast
<
float
&>(
ANativeWindow
::
ydpi
) =
fbDev
->
ydpi
;
const_cast
<
int
&>(
ANativeWindow
::
minSwapInterval
) =
fbDev
->
minSwapInterval
;
const_cast
<
int
&>(
ANativeWindow
::
maxSwapInterval
) =
fbDev
->
maxSwapInterval
;
ANativeWindow
::
setSwapInterval
=
setSwapInterval
;
ANativeWindow
::
dequeueBuffer
=
dequeueBuffer
;
ANativeWindow
::
queueBuffer
=
queueBuffer
;
ANativeWindow
::
query
=
query
;
ANativeWindow
::
perform
=
perform
;
ANativeWindow
::
dequeueBuffer_DEPRECATED
=
dequeueBuffer_DEPRECATED
;
ANativeWindow
::
lockBuffer_DEPRECATED
=
lockBuffer_DEPRECATED
;
ANativeWindow
::
queueBuffer_DEPRECATED
=
queueBuffer_DEPRECATED
;
}
int
FramebufferNativeWindow
::
setSwapInterval
(
ANativeWindow
*
window
,
int
interval
)
{
return
fb
->
setSwapInterval
(
fb
,
interval
);
}
//opengl要一个图像缓冲区,要后台绘制了
int
FramebufferNativeWindow
::
dequeueBuffer
(
ANativeWindow
*
window
,
ANativeWindowBuffer
**
buffer
,
int
*
fenceFd
)
{
//根据一系列条件找到一个空闲的缓冲区,如果没有空闲的了,还的等待queuebuffer释放一个缓存
int
index
=???
*
buffer
=
self
->
buffers
[
index
].
get
();
*
fenceFd
= -1;
}
//这个buffer绘制完成,可以绘制到屏幕上了
int
FramebufferNativeWindow
::
queueBuffer
(
ANativeWindow
*
window
,
ANativeWindowBuffer
*
buffer
,
int
fenceFd
)
{
//等待其他硬件都这个buffer操作完成
sp
<
Fence
>
fence
(
new
Fence
(
fenceFd
));
fence
->
wait
(
Fence
::
TIMEOUT_NEVER
);
//绘制到屏幕上
fb
->
post
(
fb
,
handle
);
}
egl中定义了:
typedef
struct
ANativeWindow
*
EGLNativeWindowType
;
(2.)app端,临时用的的ANativeWindow,最终这个buffer会间接的提交到Framebuffer那面,显示到屏幕上。
class
Surface
:
public
ANativeObjectBase
<
ANativeWindow
,
Surface
,
RefBase
>
构造函数,跟上面的差不多吧,都先初始化ANativeWindow相关函数接口
Surface
::
Surface
(
const
sp
<
IGraphicBufferProducer
>&
bufferProducer
,
bool
controlledByApp
)
:
mGraphicBufferProducer
(
bufferProducer
)
{
ANativeWindow
::
setSwapInterval
=
hook_setSwapInterval
;
ANativeWindow
::
dequeueBuffer
=
hook_dequeueBuffer
;
ANativeWindow
::
cancelBuffer
=
hook_cancelBuffer
;
ANativeWindow
::
queueBuffer
=
hook_queueBuffer
;
ANativeWindow
::
query
=
hook_query
;
ANativeWindow
::
perform
=
hook_perform
;
ANativeWindow
::
dequeueBuffer_DEPRECATED
=
hook_dequeueBuffer_DEPRECATED
;
ANativeWindow
::
cancelBuffer_DEPRECATED
=
hook_cancelBuffer_DEPRECATED
;
ANativeWindow
::
lockBuffer_DEPRECATED
=
hook_lockBuffer_DEPRECATED
;
ANativeWindow
::
queueBuffer_DEPRECATED
=
hook_queueBuffer_DEPRECATED
;
const_cast
<
int
&>(
ANativeWindow
::
minSwapInterval
) = 0;
const_cast
<
int
&>(
ANativeWindow
::
maxSwapInterval
) = 1;
mReqWidth
= 0;
mReqHeight
= 0;
mReqFormat
= 0;
.....
}
//opengl要一个图像缓冲区,要后台绘制了
int
Surface
::
dequeueBuffer
(
android_native_buffer_t
**
buffer
,
int
*
fenceFd
) {
sp
<
Fence
>
fence
;
// producer(BufferQueue)中获取一段空闲的图像缓冲区,这个内部也是通过硬件抽象层的Gralloc申请的
status_t
result
=
mGraphicBufferProducer
->
dequeueBuffer
(&
buf
, &
fence
,
mSwapIntervalZero
,
reqW
,
reqH
,
mReqFormat
,
mReqUsage
);
sp
<
GraphicBuffer
>&
gbuf
(
mSlots
[
buf
].
buffer
);
if
((
result
&
IGraphicBufferProducer
::
BUFFER_NEEDS_REALLOCATION
) ||
gbuf
== 0) {
result
=
mGraphicBufferProducer
->
requestBuffer
(
buf
, &
gbuf
);
}
*
fenceFd
=
fence
->
dup
();
*
buffer
=
gbuf
.
get
();
return
OK
;
}
//这个buffer绘制完成,可以用了啊
int
Surface
::
queueBuffer
(
android_native_buffer_t
*
buffer
,
int
fenceFd
) {
Rect
crop
;
mCrop
.
intersect
(
Rect
(
buffer
->
width
,
buffer
->
height
), &
crop
);
sp
<
Fence
>
fence
(
fenceFd
>= 0 ?
new
Fence
(
fenceFd
) :
Fence
::
NO_FENCE
);
IGraphicBufferProducer
::
QueueBufferOutput
output
;
IGraphicBufferProducer
::
QueueBufferInput
input
(
timestamp
,
isAutoTimestamp
,
crop
,
mScalingMode
,
mTransform
,
mSwapIntervalZero
,
fence
);
//
producer(BufferQueue)添加一段填充好的buffer,需要渲染buffer的就看着办吧
status_t err = mGraphicBufferProducer-> queueBuffer(i , input, &output);
uint32_t
numPendingBuffers
= 0;
output
.
deflate
(&
mDefaultWidth
, &
mDefaultHeight
, &
mTransformHint
,
&
numPendingBuffers
);
return
err
;
}
mGraphicBufferProducer (BufferQueue)入队,出队是 一个跨进程的操作,他们通过Binder通讯。
BufferQueue是一个典型的生产消费结构,生产者加工好数据丢进来,消耗者发现有数据后马上消耗掉,这个以后再分析。
3.opengl如何使用这个ANativeWindow的呢
android中opengl环境的搭建是由EGL帮忙完成的,opengl是一组跨进程的api,
NativeWindowType就是一个
ANativeWindow
typedef
struct
ANativeWindow
*
EGLNativeWindowType
;
EGLSurface
eglCreateWindowSurface
(
EGLDisplay
dpy
,
EGLConfig
config
, NativeWindowType window
,
const
EGLint
*
attrib_list
)
{
//保存了加载的opengl相关的so导出接口,egl接口
egl_connection_t
*
cnx
=
NULL
;
egl_display_ptr
dp
=
validate_display_connection
(
dpy
,
cnx
);
//可以想象一下就是吧window包装成一个EGlSurface,
cnx
->
egl是so提供的一系类函数指针
EGLSurface
surface
=
cnx
->
egl
.
eglCreateWindowSurface
(
iDpy
,
config
,
window
,
attrib_list
);
}
最后
以上就是自信冰淇淋为你收集整理的ANativeWindow的全部内容,希望文章能够帮你解决ANativeWindow所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复