OpenGL ES与EGL的关系(二十一),完美讲解内存缓存LruCache实现原理

这篇具有很好参考价值的文章主要介绍了OpenGL ES与EGL的关系(二十一),完美讲解内存缓存LruCache实现原理。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

glEnable(GL_TEXTURE_2D);

glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

const GLint xc = (mWidth - mAndroid[0].w) / 2;

const GLint yc = (mHeight - mAndroid[0].h) / 2;

const Rect updateRect(xc, yc, xc + mAndroid[0].w, yc + mAndroid[0].h);

glScissor(updateRect.left, mHeight - updateRect.bottom, updateRect.width(),

updateRect.height());

// Blend state

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

const nsecs_t startTime = systemTime();

do {

nsecs_t now = systemTime();

double time = now - startTime;

float t = 4.0f * float(time / us2ns(16667)) / mAndroid[1].w;

GLint offset = (1 - (t - floorf(t))) * mAndroid[1].w;

GLint x = xc - offset;

glDisable(GL_SCISSOR_TEST);

glClear(GL_COLOR_BUFFER_BIT);

glEnable(GL_SCISSOR_TEST);

glDisable(GL_BLEND);

glBindTexture(GL_TEXTURE_2D, mAndroid[1].name);

glDrawTexiOES(x, yc, 0, mAndroid[1].w, mAndroid[1].h);

glDrawTexiOES(x + mAndroid[1].w, yc, 0, mAndroid[1].w, mAndroid[1].h);

glEnable(GL_BLEND);

glBindTexture(GL_TEXTURE_2D, mAndroid[0].name);

glDrawTexiOES(xc, yc, 0, mAndroid[0].w, mAndroid[0].h);

EGLBoolean res = eglSwapBuffers(mDisplay, mSurface);

if (res == EGL_FALSE)

break;

// 12fps: don’t animate too fast to preserve CPU

const nsecs_t sleepTime = 83333 - ns2us(systemTime() - now);

if (sleepTime > 0)

usleep(sleepTime);

checkExit();

} while (!exitPending());

glDeleteTextures(1, &mAndroid[0].name);

glDeleteTextures(1, &mAndroid[1].name);

return false;

}

EGL加载OpenGL ES库


从上面的例子中,我们发现通过egl_函数调用后,直接就能调用gl_函数去画图了,为何?难道在egl*函数调用过程中,已经将opengl相关实现的库加载了吗?

涉及的库


首先,由于涉及的库较多,先列出来(高通平台,原生的只有前4个),

//算是android中的egl库,用来加载具体的实现

system\lib\libEGL.so

//opengl具体实现的wrapper

system\lib\libGLESv1_CM.so

system\lib\libGLESv2.so

//opengl软件实现,即agl

system\lib\egl\libGLES_android.so

//egl的实现

system\vendor\lib\egl\libEGL_adreno.so

//opengl硬件实现

system\vendor\lib\egl\libGLESv1_CM_adreno.so

system\vendor\lib\egl\libGLESv2_adreno.so

库的加载


继续以bootanimation为例,在bootanimation的makefile中,使用了libEGL 库,

// frameworks\base\cmds\bootanimation\Android.mk

LOCAL_SHARED_LIBRARIES := \

libcutils \

liblog \

libandroidfw \

libutils \

libbinder \

libui \

libskia \

libEGL \

libGLESv1_CM \

libgui

LOCAL_MODULE:= bootanimation

frameworks\native\opengl\libs\Android.mk中,定义了libEGL.so,makefile中并未指定特殊的存放path,所以最终生成的库保存在system\lib\libEGL.so这个库是用来加载具体的egl和opengl实现的,起到桥梁作用,需要和EGL实现的库区分开。

//frameworks\native\opengl\libs\Android.mk

include $(CLEAR_VARS)

LOCAL_SRC_FILES:= \

EGL/egl_tls.cpp \

EGL/egl_cache.cpp \

EGL/egl_display.cpp \

EGL/egl_object.cpp \

EGL/egl.cpp \

EGL/eglApi.cpp \

EGL/trace.cpp \

EGL/getProcAddress.cpp.arm \

EGL/Loader.cpp \

LOCAL_MODULE:= libEGL

include $(BUILD_SHARED_LIBRARY)

接下来看eglGetDisplay(),这个函数就是在system\lib\libEGL.so中实现的。

EGLDisplay eglGetDisplay(EGLNativeDisplayType display)

{

clearError();

uint32_t index = uint32_t(display);

if (index >= NUM_DISPLAYS) {

return setError(EGL_BAD_PARAMETER, EGL_NO_DISPLAY);

}

//从函数名上看是加载相关实现

if (egl_init_drivers() == EGL_FALSE) {

return setError(EGL_BAD_PARAMETER, EGL_NO_DISPLAY);

}

EGLDisplay dpy = egl_display_t::getFromNativeDisplay(display);

return dpy;

}

EGLBoolean egl_init_drivers() {

EGLBoolean res;

pthread_mutex_lock(&sInitDriverMutex);

res = egl_init_drivers_locked();

pthread_mutex_unlock(&sInitDriverMutex);

return res;

}

static EGLBoolean egl_init_drivers_locked() {

if (sEarlyInitState) {

// initialized by static ctor. should be set here.

return EGL_FALSE;

}

// get our driver loader

Loader& loader(Loader::getInstance());

// dynamically load our EGL implementation

egl_connection_t* cnx = &gEGLImpl;

if (cnx->dso == 0) {

//gHooks保存的是gl开头的函数实现

cnx->hooks[egl_connection_t::GLESv1_INDEX] =

&gHooks[egl_connection_t::GLESv1_INDEX];

cnx->hooks[egl_connection_t::GLESv2_INDEX] =

&gHooks[egl_connection_t::GLESv2_INDEX];

cnx->dso = loader.open(cnx);

}

return cnx->dso ? EGL_TRUE : EGL_FALSE;

egl_connection_t gEGLImpl;

gl_hooks_t gHooks[2];

struct egl_connection_t {

enum {

GLESv1_INDEX = 0,

GLESv2_INDEX = 1

};

inline egl_connection_t() : dso(0) { }

void * dso;

gl_hooks_t * hooks[2];

EGLint major;

EGLint minor;

//保存egl 实现

egl_t egl;

void* libGles1;

void* libGles2;

};

// 还能这么用,以前真是没用过

// 将EGL/egl_entries.in文件include进来,都是些egl entry

struct egl_t {

#include “EGL/egl_entries.in”

};

//将entries.in文件include进来

struct gl_hooks_t {

struct gl_t {

#include “entries.in”

} gl;

struct gl_ext_t {

__eglMustCastToProperFunctionPointerType extensions[MAX_NUMBER_OF_GL_EXTENSIONS];

} ext;

};

EGL/http://egl_entries.in文件中都是如下的一条一条entry,以egl开头,都是函数声明,

EGL_ENTRY(EGLDisplay, eglGetDisplay, NativeDisplayType)

http://entries.in文件中,都是以gl开头的entry,都是函数声明,

GL_ENTRY(void, glActiveShaderProgramEXT, GLuint pipeline, GLuint program)

从下面的宏可以看出,转换完成后,上面的entry都是返回值,函数名,函数参数的型式。

#undef GL_ENTRY

#undef EGL_ENTRY

#define GL_ENTRY(_r, _api, …) _r (*_api)(VA_ARGS);

#define EGL_ENTRY(_r, _api, …) _r (*_api)(VA_ARGS);

所以,

struct egl_t {

EGLDisplay eglGetDisplay(NativeDisplayType );

};

struct gl_t {

void glActiveShaderProgramEXT(GLuint pipeline, GLuint program);

} gl;

下面看cnx->dso = loader.open(cnx),

void* Loader::open(egl_connection_t* cnx)

{

void* dso;

driver_t* hnd = 0;

//首先,kind为GLES,mask为EGL,GLESv1_CM ,GLESv2

//在/vendor/lib/egl和/system/lib/egl下寻找libGLES.so或者libGLES_*.so

//这里只能找到system\lib\egl\libGLES_android.so,opengl的软件实现

//但是代码中直接continue了,不使用软件实现

//所以dso返回空

dso = load_driver(“GLES”, cnx, EGL | GLESv1_CM | GLESv2);

if (dso) {

hnd = new driver_t(dso);

} else {

// Always load EGL first

// kind为EGL,mask为EGL

// 可以找到system\vendor\lib\egl\libEGL_adreno.so

// 然后填充egl相关函数

dso = load_driver(“EGL”, cnx, EGL);

if (dso) {

hnd = new driver_t(dso);

//找到system\vendor\lib\egl\libGLESv1_CM_adreno.so库,

//填充gl相关函数

hnd->set( load_driver(“GLESv1_CM”, cnx, GLESv1_CM), GLESv1_CM );

//找到system\vendor\lib\egl\libGLESv2_adreno.so库,

//填充gl相关函数

hnd->set( load_driver(“GLESv2”, cnx, GLESv2), GLESv2 );

}

}

LOG_ALWAYS_FATAL_IF(!hnd, “couldn’t find an OpenGL ES implementation”);

//上面是opengle的实现,下面的cnx->libGles2和libGles1是gles实现的wrapper

// 只是打开/system/lib/libGLESv2.so和/system/lib/libGLESv1_CM.so这两个库,将地址返回给cnx

cnx->libGles2 = load_wrapper(“/system/lib/libGLESv2.so”);

cnx->libGles1 = load_wrapper(“/system/lib/libGLESv1_CM.so”);

LOG_ALWAYS_FATAL_IF(!cnx->libGles2 || !cnx->libGles1,

“couldn’t load system OpenGL ES wrapper libraries”);

return (void*)hnd;

}

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
OpenGL ES与EGL的关系(二十一),完美讲解内存缓存LruCache实现原理,2024年程序员学习,elasticsearch,缓存,大数据
OpenGL ES与EGL的关系(二十一),完美讲解内存缓存LruCache实现原理,2024年程序员学习,elasticsearch,缓存,大数据
OpenGL ES与EGL的关系(二十一),完美讲解内存缓存LruCache实现原理,2024年程序员学习,elasticsearch,缓存,大数据
OpenGL ES与EGL的关系(二十一),完美讲解内存缓存LruCache实现原理,2024年程序员学习,elasticsearch,缓存,大数据
OpenGL ES与EGL的关系(二十一),完美讲解内存缓存LruCache实现原理,2024年程序员学习,elasticsearch,缓存,大数据
OpenGL ES与EGL的关系(二十一),完美讲解内存缓存LruCache实现原理,2024年程序员学习,elasticsearch,缓存,大数据
OpenGL ES与EGL的关系(二十一),完美讲解内存缓存LruCache实现原理,2024年程序员学习,elasticsearch,缓存,大数据

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
OpenGL ES与EGL的关系(二十一),完美讲解内存缓存LruCache实现原理,2024年程序员学习,elasticsearch,缓存,大数据

总结

Android架构学习进阶是一条漫长而艰苦的道路,不能靠一时激情,更不是熬几天几夜就能学好的,必须养成平时努力学习的习惯。所以:贵在坚持!

上面分享的字节跳动公司2020年的面试真题解析大全,笔者还把一线互联网企业主流面试技术要点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节。

就先写到这,码字不易,写的很片面不好之处敬请指出,如果觉得有参考价值的朋友也可以关注一下我

①「Android面试真题解析大全」PDF完整高清版+②「Android面试知识体系」学习思维导图压缩包阅读下载,最后觉得有帮助、有需要的朋友可以点个赞

OpenGL ES与EGL的关系(二十一),完美讲解内存缓存LruCache实现原理,2024年程序员学习,elasticsearch,缓存,大数据

OpenGL ES与EGL的关系(二十一),完美讲解内存缓存LruCache实现原理,2024年程序员学习,elasticsearch,缓存,大数据

OpenGL ES与EGL的关系(二十一),完美讲解内存缓存LruCache实现原理,2024年程序员学习,elasticsearch,缓存,大数据

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**

如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
[外链图片转存中…(img-aYq3Pb8s-1711693968677)]

总结

Android架构学习进阶是一条漫长而艰苦的道路,不能靠一时激情,更不是熬几天几夜就能学好的,必须养成平时努力学习的习惯。所以:贵在坚持!

上面分享的字节跳动公司2020年的面试真题解析大全,笔者还把一线互联网企业主流面试技术要点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节。

就先写到这,码字不易,写的很片面不好之处敬请指出,如果觉得有参考价值的朋友也可以关注一下我

①「Android面试真题解析大全」PDF完整高清版+②「Android面试知识体系」学习思维导图压缩包阅读下载,最后觉得有帮助、有需要的朋友可以点个赞

[外链图片转存中…(img-Fw4iD0eG-1711693968677)]

[外链图片转存中…(img-iQSnZsgd-1711693968678)]

[外链图片转存中…(img-wOXS8p6P-1711693968678)]

本文已被CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》收录文章来源地址https://www.toymoban.com/news/detail-847160.html

到了这里,关于OpenGL ES与EGL的关系(二十一),完美讲解内存缓存LruCache实现原理的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Android OpenGL开发】OpenGL ES与EGL介绍

    OpenGL(Open Graphics Library)是一个跨编程语言、跨平台的编程图形程序接口,主要用于图像的渲染。 Android提供了简化版的OpenGL接口,即OpenGL ES。 早先定义 OpenGL ES 是 OpenGL 的嵌入式设备版本,用于移动端平台(Android、iOS),但由于嵌入式设备要求的是高性能,所以一些其它纯

    2024年02月04日
    浏览(76)
  • Android OpenGL ES 学习(十) – GLSurfaceView 源码解析GL线程以及自定义 EGL

    OpenGL 学习教程 Android OpenGL ES 学习(一) – 基本概念 Android OpenGL ES 学习(二) – 图形渲染管线和GLSL Android OpenGL ES 学习(三) – 绘制平面图形 Android OpenGL ES 学习(四) – 正交投影 Android OpenGL ES 学习(五) – 渐变色 Android OpenGL ES 学习(六) – 使用 VBO、VAO 和 EBO/IBO 优化程序 Android OpenG

    2024年02月05日
    浏览(33)
  • hyperf 二十一 数据库 模型关系

    教程:Hyperf 根据文档 一对一:Model::hasOne(被关联模型,被关联模型外键,本模型被关联的字段) 一对多:Model::hasMany(被关联模型,被关联模型外键,本模型被关联的字段) 反向一对多:Model::belongsTo(被关联模型,本模型外键,被关联模型的对应字段,关联关系) 多对多:Model:

    2024年01月17日
    浏览(33)
  • 【OpenGL ES】缓存——缓冲区对象【I

    //创建编译加载 GLuint LoadShader(int type, char *shaderCode); //链接统一程序 GLuint linkProgram(GLuint vertexShader, GLuint fragmentShader); //用于求数组长度 template GLsizei getArrayLen(T array) { } //float 四个字节 const GLint BYTES_PER_FLOAT = 4; //xyz坐标 const GLint COORDS_PER_VERTEX = 3; //RGBA通道 const GLint COORDS_PER_COLO

    2024年04月14日
    浏览(26)
  • JVM工作原理与实战(二十一):内存管理

    JVM工作原理与实战 RabbitMQ入门指南 从零开始了解大数据 目录 专栏导航 前言 一、不同语言的内存管理 1.C/C++的内存管理 2.Java的内存管理 二、垃圾回收的对比 1.自动垃圾回收与手动垃圾回收的对比 2.优点与缺点 总结 JVM作为Java程序的运行环境,其负责解释和执行字节码,管理

    2024年01月21日
    浏览(32)
  • 操作系统原理 —— 内存动态分区分配算法(二十一)

    在上一个章节我们讲了 内存连续分配 的几种方式,有单一、固定、动态这三种,在固定、动态这种里面,操作系统会记录空闲分区表,这个表是用来记录当前空闲的内存。 那么在之后有新的进程装入内存,需要从空闲分区表中找到一块比较合适的空闲内存,该怎么找呢?

    2024年02月08日
    浏览(37)
  • 数据结构(超详细讲解!!)第二十一节 特殊矩阵的压缩存储

    值相同的元素只存储一次 压缩掉对零元的存储,只存储非零元 特殊形状矩阵: 是指非零元(如值相同的元素)或零元素分布具有一定规律性的矩阵。 如: 对称矩阵 上三角矩阵   下三角矩阵 对角矩阵   准对角矩阵 三角矩阵大体分为三类:下三角矩阵、上三角矩阵和对称

    2024年02月04日
    浏览(37)
  • Android OpenGL EGL使用——自定义相机

    如果要使用OpenGl来自定义相机,EGL还是需要了解下的。 可能大多数开发者使用过OpengGL但是不知道EGL是什么?EGL的作用是什么?这其实一点都不奇怪,因为Android中的GlSurfaceView已经将EGL环境都给配置好了,你一直在使用,只是不知道他的存在罢了。 很多人可能在使用OpenGl ES渲

    2024年01月22日
    浏览(30)
  • 第二十一章 Prim算法与Kruskal算法(通俗证明与详细讲解)

    我们先解释一下什么是最小生成树。 这个概念是基于图的,如果说存在一条路线串通起来了所有的点,那么这条路线就叫做生成树。而在这些路线中最短的那一条就叫做最小生成树。 如上图所示,图中的红色路线就是一个生成树,假设这条红色路线是众多生成树路线中最小

    2024年02月11日
    浏览(26)
  • CPU、内存、缓存的关系

    (1)CPU(Central Processing Unit) 中央处理器 (2)内存 内存用于暂时存放CPU中的运算数据,以及与硬盘等外部存储器交换的数据。它是外存与CPU进行沟通的桥梁,内存的运行决定计算机整体运行快慢。 缓冲区(Buffer)是内存空间的一部分,在内存中预留了一定的存储空间,用

    2024年02月08日
    浏览(27)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包