【无标题】

GLES 层

EGL加载器初始化

所有标准入口点均未修改地填充后,将实例化一个GLES LayerLoader。如果启用了调试层,LayerLoader 将扫描指定目录中的层,就像Vulkan 加载器一样。

如果启用了分层功能,加载器将搜索并枚举指定的图层列表。图层列表将由冒号分隔的文件名指定(请参阅下文的启用图层)。

图层将按照指定的顺序进行遍历,因此第一个图层将直接位于应用程序下方。对于每个图层,它将跟踪该图层的两个入口点: AndroidGLESLayer_InitializeAndroidGLESLayer_GetProcAddress

typedef   void  ** PFNEGLGETNEXTLAYERPROCADDRESSPROC )(void  *const   char  *);
无效*   AndroidGLESLayer_Initialize (无效* layer_id , PFNEGLGETNEXTLAYERPROCADDRESSPROC get_next_layer_proc_address ))

AndroidGLESLayer_Initialize是一个新函数,它为要使用的层提供了一个标识符 (layer_id),以及一个可以调用来查找层下函数的入口点。入口点的使用方式如下:

const   char  * func =   "eglFoo"  ;
void  * gpa =   get_next_layer_proc_address  ( layer_id,func ) ;

请注意,仅提供GLES2+ 入口点。如果某个层尝试进行独立的GLES 1.x 调用,它们将被路由到GLES2+ 库,这可能会导致行为不符合预期。应用对1.x 的调用不会受到影响。

AndroidGLESLayer_GetProcAddress 是专为此分层系统设计的一个新函数。它获取该层完成后应调用的链中下一个调用的地址。如果只有一个层,则对于大多数函数,next 将直接指向驱动程序。

void *  AndroidGLESLayer_GetProcAddress ( const  char  * funcName , EGLFuncPointer next )

对于找到的每个层,GLES LayerLoader 都会调用 AndroidGLESLayer_Initialize ,然后遍历 libEGL 的函数列表,并针对所有已知函数调用 AndroidGLESLayer_GetProcAddress 。该层可以使用任何方式跟踪下一个地址。如果该层未拦截该函数,则 AndroidGLESLayer_GetProcAddress必须返回与其传入的相同函数地址。然后,LayerLoader 将更新函数钩子列表,使其指向该层的入口点。

图层无需使用 AndroidGLESLayer_Initialize或get_next_layer_proc_address 提供的信息执行任何操作,但提供这些信息可以让现有图层(如 GAPID 和 RenderDoc)更轻松地支持 Android。这样​​,图层就可以独立查找函数(即无需等待 AndroidGLESLayer_GetProcAddress`的调用)。如果图层查找函数调用,则必须确保使用 gen_next_layer_proc_address 而不是 eglGetProcAddress,否则将无法获得准确的答案。eglGetProcAddress 必须沿链向下传递到平台。

##放置图层

按照优先级顺序查找图层
1.根目录的系统位置
这需要 root 权限
bash adb root adb disable-verity adb重启 adb root adb shell setenforce 0 adb shell mkdir -p /数据/本地/调试/gles adb push <layer>.so /data/local/debug/gles/

  1. Application’s base directory
    Target application must be debuggable, or you must have root access:

    adb push libGLTrace.so /data/local/tmp
    adb shell run-as com.android.gl2jni cp /data/local/tmp/libGLTrace.so .
    adb shell run-as com.android.gl2jni ls | grep libGLTrace
     libGLTrace.so
    
  2. External APK
    Determine the ABI of your target application, then install an APK containing the layers you wish to load:

    adb install --abi armeabi-v7a layers.apk
    
  3. In the target application’s APK

Enabling layers

Per application

Note these settings will persist across reboots:

# Enable layers
adb shell settings put global enable_gpu_debug_layers 1

# Specify target application
adb shell settings put global gpu_debug_app <package_name>

# Specify layer list (from top to bottom)
adb shell settings put global gpu_debug_layers_gles <layer1:layer2:layerN>

# Specify a package to search for layers
adb shell settings put global gpu_debug_layer_app <layer_package>

To disable the per-app layers:

adb shell settings delete global enable_gpu_debug_layers
adb shell settings delete global gpu_debug_app
adb shell settings delete global gpu_debug_layers_gles
adb shell settings delete global gpu_debug_layer_app

Globally

These will be cleared on reboot:

# This will attempt to load layers for all applications, including native executables
adb shell setprop debug.gles.layers <layer1:layer2:layerN>

Creating a layer

Layers must expose the following two functions described above:

AndroidGLESLayer_Initialize
AndroidGLESLayer_GetProcAddress

For a simple layer that just wants to intercept a handful of functions, a passively initialized layer is the way to go. It can simply wait for the EGL Loader to initialize the function it cares about. See below for an example of creating a passive layer.

For more formalized layers that need to fully initialize up front, or layers that needs to look up extensions not known to the EGL loader, active layer initialization is the way to go. The layer can utilize get_next_layer_proc_address provided by AndroidGLESLayer_Initialize to look up a function at any time. The layer must still respond to AndroidGLESLayer_GetProcAddress requests from the loader so the platform knows where to route calls. See below for an example of creating an active layer.

Example Passive Layer Initialization

namespace {

std::unordered_map<std::string, EGLFuncPointer> funcMap;

EGLAPI EGLBoolean EGLAPIENTRY glesLayer_eglChooseConfig (
  EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size,
  EGLint *num_config) {

  EGLFuncPointer entry = funcMap["eglChooseConfig"];

  typedef EGLBoolean (*PFNEGLCHOOSECONFIGPROC)(
    EGLDisplay, const EGLint*, EGLConfig*, EGLint, EGLint*);

  PFNEGLCHOOSECONFIGPROC next = reinterpret_cast<PFNEGLCHOOSECONFIGPROC>(entry);

  return next(dpy, attrib_list, configs, config_size, num_config);
}

EGLAPI EGLFuncPointer EGLAPIENTRY eglGPA(const char* funcName) {

  #define GETPROCADDR(func) if(!strcmp(funcName, #func)) { \
    return (EGLFuncPointer)glesLayer_##func; }

  GETPROCADDR(eglChooseConfig);

  // Don't return anything for unrecognized functions
  return nullptr;
}

EGLAPI void EGLAPIENTRY glesLayer_InitializeLayer(
  void* layer_id, PFNEGLGETNEXTLAYERPROCADDRESSPROC get_next_layer_proc_address) {
     // This function is purposefully empty, since this layer does not proactively
     // look up any entrypoints
  }

EGLAPI EGLFuncPointer EGLAPIENTRY glesLayer_GetLayerProcAddress(
  const char* funcName, EGLFuncPointer next) {
  EGLFuncPointer entry = eglGPA(funcName);
  if (entry != nullptr) {
    funcMap[std::string(funcName)] = next;
    return entry;
  }
  return next;
}

}  // namespace

extern "C" {
  __attribute((visibility("default"))) EGLAPI void AndroidGLESLayer_Initialize(
    void* layer_id, PFNEGLGETNEXTLAYERPROCADDRESSPROC get_next_layer_proc_address) {
    return (void)glesLayer_InitializeLayer(layer_id, get_next_layer_proc_address);
  }
  __attribute((visibility("default"))) EGLAPI void* AndroidGLESLayer_GetProcAddres(
    const char *funcName, EGLFuncPointer next) {
    return (void*)glesLayer_GetLayerProcAddress(funcName, next);
  }
}

Example Active Layer Initialization

namespace {

std::unordered_map<std::string, EGLFuncPointer> funcMap;

EGLAPI EGLBoolean EGLAPIENTRY glesLayer_eglChooseConfig (
  EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size,
  EGLint *num_config) {

  EGLFuncPointer entry = funcMap["eglChooseConfig"];

  typedef EGLBoolean (*PFNEGLCHOOSECONFIGPROC)(
    EGLDisplay, const EGLint*, EGLConfig*, EGLint, EGLint*);

  PFNEGLCHOOSECONFIGPROC next = reinterpret_cast<PFNEGLCHOOSECONFIGPROC>(entry);
j
  return next(dpy, attrib_list, configs, config_size, num_config);
}

EGLAPI EGLFuncPointer EGLAPIENTRY eglGPA(const char* funcName) {

  #define GETPROCADDR(func) if(!strcmp(funcName, #func)) { \
    return (EGLFuncPointer)glesLayer_##func; }

  GETPROCADDR(eglChooseConfig);

  // Don't return anything for unrecognized functions
  return nullptr;
}

EGLAPI void EGLAPIENTRY glesLayer_InitializeLayer(
  void* layer_id, PFNEGLGETNEXTLAYERPROCADDRESSPROC get_next_layer_proc_address) {

  // Note: This is where the layer would populate its function map with all the
  // functions it cares about
  const char* func = “eglChooseConfig”;
  funcMap[func] = get_next_layer_proc_address(layer_id, func);
}

EGLAPI EGLFuncPointer EGLAPIENTRY glesLayer_GetLayerProcAddress(
  const char* funcName, EGLFuncPointer next) {
  EGLFuncPointer entry = eglGPA(funcName);
  if (entry != nullptr) {
    return entry;
  }

  return next;
}

}  // namespace

extern "C" {
  __attribute((visibility("default"))) EGLAPI void AndroidGLESLayer_Initialize(
    void* layer_id, PFNEGLGETNEXTLAYERPROCADDRESSPROC get_next_layer_proc_address) {
    return (void)glesLayer_InitializeLayer(layer_id, get_next_layer_proc_address);
  }
  __attribute((visibility("default"))) EGLAPI void* AndroidGLESLayer_GetProcAddres(
    const char *funcName, EGLFuncPointer next) {
    return (void*)glesLayer_GetLayerProcAddress(funcName, next);
  }
}

Caveats

Only supports GLES 2.0+.

When layering is enabled, GLES 1.x exclusive functions will continue to route to GLES 1.x drivers. But functions shared with GLES 2.0+ (like glGetString) will be routed to 2.0+ drivers, which can cause confusion.

FAQ

  • Who can use layers?
    • GLES Layers can be loaded by any debuggable application, or for any application if you have root access
  • How do we know if layers are working on a device?
    • This feature is backed by Android CTS, so you can run atest CtsGpuToolsHostTestCases
  • How does a app determine if this feature is supported?
    • There are two ways. First you can check against the version of Android.
      # Q is the first that will support this, so look for `Q` or 10 for release
      adb shell getprop ro.build.version.sdk 
      # Or look for the SDK version, which should be 29 for Q
      adb shell getprop ro.build.version.sdk
      
    • Secondly, if you want to determine from an application that can’t call out to ADB for this, you can check for the EGL_ANDROID_GLES_layers. It simply indicates support of this layering system:
      std::string display_extensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
      if (display_extensions.find("EGL_ANDROID_GLES_layers") != std::string::npos)
      {
         // Layers are supported!
      }
      

欢迎使用Markdown编辑器

你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。

新的改变

我们对Markdown编辑器进行了一些功能拓展与语法支持,除了标准的Markdown编辑器功能,我们增加了如下几点新功能,帮助你用它写博客:

  1. 全新的界面设计 ,将会带来全新的写作体验;
  2. 在创作中心设置你喜爱的代码高亮样式,Markdown 将代码片显示选择的高亮样式 进行展示;
  3. 增加了 图片拖拽 功能,你可以将本地的图片直接拖拽到编辑区域直接展示;
  4. 全新的 KaTeX数学公式 语法;
  5. 增加了支持甘特图的mermaid语法1 功能;
  6. 增加了 多屏幕编辑 Markdown文章功能;
  7. 增加了 焦点写作模式、预览模式、简洁写作模式、左右区域同步滚轮设置 等功能,功能按钮位于编辑区域与预览区域中间;
  8. 增加了 检查列表 功能。

功能快捷键

撤销:Ctrl/Command + Z
重做:Ctrl/Command + Y
加粗:Ctrl/Command + B
斜体:Ctrl/Command + I
标题:Ctrl/Command + Shift + H
无序列表:Ctrl/Command + Shift + U
有序列表:Ctrl/Command + Shift + O
检查列表:Ctrl/Command + Shift + C
插入代码:Ctrl/Command + Shift + K
插入链接:Ctrl/Command + Shift + L
插入图片:Ctrl/Command + Shift + G
查找:Ctrl/Command + F
替换:Ctrl/Command + G

合理的创建标题,有助于目录的生成

直接输入1次#,并按下space后,将生成1级标题。
输入2次#,并按下space后,将生成2级标题。
以此类推,我们支持6级标题。有助于使用TOC语法后生成一个完美的目录。

如何改变文本的样式

强调文本 强调文本

加粗文本 加粗文本

标记文本

删除文本

引用文本

H2O is是液体。

210 运算结果是 1024.

插入链接与图片

链接: link.

图片: Alt

带尺寸的图片: Alt

居中的图片: Alt

居中并且带尺寸的图片: Alt

当然,我们为了让用户更加便捷,我们增加了图片拖拽功能。

如何插入一段漂亮的代码片

博客设置页面,选择一款你喜欢的代码片高亮样式,下面展示同样高亮的 代码片.

// An highlighted block
var foo = 'bar';

生成一个适合你的列表

  • 项目
    • 项目
      • 项目
  1. 项目1
  2. 项目2
  3. 项目3
  • 计划任务
  • 完成任务

创建一个表格

一个简单的表格是这么创建的:

项目Value
电脑$1600
手机$12
导管$1

设定内容居中、居左、居右

使用:---------:居中
使用:----------居左
使用----------:居右

第一列第二列第三列
第一列文本居中第二列文本居右第三列文本居左

SmartyPants

SmartyPants将ASCII标点字符转换为“智能”印刷标点HTML实体。例如:

TYPEASCIIHTML
Single backticks'Isn't this fun?'‘Isn’t this fun?’
Quotes"Isn't this fun?"“Isn’t this fun?”
Dashes-- is en-dash, --- is em-dash– is en-dash, — is em-dash

创建一个自定义列表

Markdown
Text-to- HTML conversion tool
Authors
John
Luke

如何创建一个注脚

一个具有注脚的文本。2

注释也是必不可少的

Markdown将文本转换为 HTML

KaTeX数学公式

您可以使用渲染LaTeX数学表达式 KaTeX:

Gamma公式展示 Γ ( n ) = ( n − 1 ) ! ∀ n ∈ N \Gamma(n) = (n-1)!\quad\forall n\in\mathbb N Γ(n)=(n1)!nN 是通过欧拉积分

Γ ( z ) = ∫ 0 ∞ t z − 1 e − t d t   . \Gamma ( z ) = \int _0^ \infty t^ { z-1 } e^ { -t } dt \, . Γ(z)=0tz1etdt.

你可以找到更多关于的信息 LaTeX 数学表达式[here][1].

新的甘特图功能,丰富你的文章

“美人鱼
甘特图
日期格式 YYYY-MM-DD
标题 为 Mermaid 添加 GANTT 图表功能
section 现有任务
已完成 :done, des1, 2014-01-06,2014-01-08
进行中 :active, des2, 2014-01-09, 3d
计划一 : des3, after des2, 5d
计划二 : des4, after des3, 5d

- 关于 **甘特图** 语法,参考 [这儿][2],

## UML 图表

可以使用UML图表进行渲染。 [Mermaid](https://mermaidjs.github.io/). 例如下面产生的一个序列图:

“美人鱼
序列图
张三 ->> 李四: 你好!李四, 最近怎么样?
李四-->>王五: 你最近怎么样,王五?
李四--x 张三: 我很好,谢谢!
李四-x 王五: 我很好,谢谢!
Note right of 王五: 李四想了很长时间, 文字太长了<br/>不适合放在一行.

李四-->>张三: 打量着王五...
张三->>王五: 很好... 王五, 你怎么样?

这将产生一个流程图。 :

“美人鱼
图LR
A[长方形] – 链接 --> B((圆))
A --> C(圆角长方形)
B --> D{菱形}
C–>D


- 关于 **Mermaid** 语法,参考 [这儿][3],

## FLowchart流程图

我们依旧会支持flowchart的流程图:
“美人鱼
流程图
st=>start: 开始
e=>end: 结束
op=>operation: 我的操作
cond=>condition: 确认?

st->op->cond
cond(是)->e
cond(无)->op
  • 关于 Flowchart流程图 语法,参考 [这儿][4].

导出与导入

导出

如果你想尝试使用此编辑器, 你可以在此篇文章任意编辑。当你完成了一篇文章的写作, 在上方工具栏找到 文章导出 ,生成一个.md文件或者.html文件进行本地保存。

导入

如果你想加载一篇你写过的.md文件,在上方工具栏可以选择导入功能进行对应扩展名的文件导入,
继续你的创作。

[ 1 ]: http://meta.math.stackexchange.com/questions/5020/mathjax-basic-tutorial-and-quick-reference
[ 2 ]: https: //mermaidjs.github.io/
[ 3 ]: https: //mermaidjs.github.io/
[ 4 ]: http: //adrai.github.io/flowchart.js/


  1. mermaid语法说明 ↩︎

  2. 注脚的解释 ↩︎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值