- 博客(17)
- 收藏
- 关注
原创 UGUI的RectTransform
网上对于RectTransform的介绍都是对于下面这个界面各个参数的介绍:或是这种:但是这些是对RectTransform一些参数的包装,但是对于其思想的理解不太明显(个人见解)。所以本文不打算介绍这些,把Debug模式打开,可以看到完全不同的参数。RectTransform区别于transform的一点的概念,而是矩形的概念。如何在父矩形空间中框出一个矩形呢,主要就两点,和。
2025-11-26 23:40:24
992
原创 游戏中的视锥剔除
游戏场景中通常有成千上万个renderer,如果每个renderer都需要提交到GPU渲染,那么会产生大量drawcall影响CPU-GPU带宽,但是最后呈现到camera只有视锥体中的对象,所以在提交到GPU之前需要在CPU端进行一次粗粒度的视锥剔除。其思想就是通过计算一个object的AABB包围盒,然后把判断该包围盒是否在视锥体内。如何判断一个AABB在视锥体内,首先,视锥体是由六个平面的组成,对于每一个平面,如果AABB都在平面外(与法线指向的区域相反)。那么这个AABB就是在视锥体外。
2025-11-23 15:35:38
579
原创 法线变换矩阵的推导
假设有两点P1和P2,则这两点的切线为tangent, 法线为normaltangentT∗normal0G∗tangentT∗M∗normal0G∗tangentT∗M∗normal0tangentT∗GT∗M∗normal0已知:tangentT∗normal0则只要使得GT。
2025-11-18 19:45:30
435
原创 ASTC adaptive scalable texture compression原理
由于混合比例的计算是线性的(origin = Color_start + α(Color_end-Color_end)), 其中0 < α < 1),所以两个端点颜色和混合比例能准确(无误差)表现的颜色向量就是Color_start指向Color_end这条向量,记为V_s。按上面4x4的例子,我们可以取出色块中对应分区的颜色集合,记为ColorA和ColorB,并通过某种方法对每个分区选出两个端点颜色A_start和A_end, B_start和B_end。比如说天空,那么就只需要一个分区就能匹配。
2025-10-22 14:36:53
351
原创 Arean TLSF内存分配算法-代码分析
这里需要先说明TLSF需要解决什么问题。TLSF全程 Two-Level Segregated Fit,是Segregated Fit内存分配算法的扩展。这里先简单介绍下,Segregated Fit算法的思想很简单,就是将内存划分成不同大小的区间,每次分配时根据所需的大小去对应的区间所对应的槽取内存。划分有,比如当前槽比上一个槽多32byte,也可能是,比如第一个槽大小是2 ^ 3byte,第二个是2 ^ 4byte,以此递推。
2025-10-19 20:03:11
966
原创 Garbage Collection in an Uncooperative Environment 翻译
摘要 本文介绍了一种无需用户程序主动配合的垃圾回收技术,重点分析了Boehm GC的优缺点。与传统方法相比,该技术仅在垃圾回收时产生开销,无需垃圾回收的程序几乎不受性能影响。其优势在于简化了编程语言对垃圾回收的支持,便于与传统编译器协作使用。但该方法存在两个潜在缺点:一是可能无法及时回收所有垃圾(内存泄漏),二是采用"stop and collect"方式可能不适合实时应用(注:现代版本已支持增量GC)。作者认为第一个问题在多数垃圾回收系统中普遍存在,实际影响有限;尽管存在第二个问题,但
2025-10-04 13:51:25
721
原创 CoreCLR 计划阶段(PlanPhase4)-计划代边界
本文应该是计划阶段的最后一篇了,之前已经讲了plug的构建和处理,最后需要进行的是计划代边界。
2025-04-08 17:21:38
295
原创 CoreCLR 计划阶段(PlanPhase3)-Pinned Plug的处理
上一篇文章中已经介绍了为普通的Plug分配空间,今天这篇文章将介绍Pinned Plug的处理方式。我们知道Pinned Plug物体可能被非托管代码访问,这就要求其所占任何时候(包括GC的时候)都不能移动,且不能被覆盖。
2025-04-05 21:36:26
909
原创 CoreCLR 计划阶段(PlanPhase2)-为普通Plug分配空间
上一篇文章中我们已经说了计划阶段会用到的两种数据结构——plug和brick。本文将从源码角度看一下Plug结构中各个字段的具体含义。到这里普通Plug的组织和为其寻找合适地址的处理应该就讲完整了。
2025-03-18 15:41:46
733
原创 CoreCLR 计划阶段(PlanPhase1)-Plug和 Brick块
接下来是最复杂的plan phase,不得不说gc.cpp文件真是长得很,3w多行,逻辑还绕,并且有得代码还没有作用(可能是历史遗留原因),gc_heap::plan_phase(int)这个函数翻来覆去看了好多遍,好了碎碎念完了。接下来要进行压缩或清扫来进行内存回收,然而如何决定要进行压缩或清扫呢?我们需要知道压缩或清扫哪个收益带来更大,如果堆中存在大量的内存碎片,压缩无疑是更好的。如果堆中仍有很多对象存活,那么我们只需要回收少部分死去对象的空间,这时候清扫效率更高。
2025-03-12 19:55:46
809
原创 CoreCLR 元数据加载(1) - DLL中的元数据存储
Net通过元数据和程序集的Manifest数据实现自我描述的特性,因为有了这些数据才能实现反射等功能。编译器在将C#等代码编译成DLL的同时,会将元数据存放在DLL的特定位置中。运行时在加载模块(Module)时通过这些元数据来获取类型信息、异常处理信息等。(累了,先这样吧)我们已经知道有哪些元数据表并且放在哪里了,接下来的问题是如何解析元数据表里面的内容。下个文章再说吧!拜拜。
2025-01-15 22:02:08
958
原创 CoreCLR mark phase源码分析
标记阶段(mark phase)作为GC的第一阶段,其主要作用是标记GC堆中分配出去的还在被引用的对象为存活,为后续的内存回收做准备。好了,到这里问题就解决了,从根对象开始,再依次标记根对象内的引用变量,就可以标记所有存活变量了。接下来的任务是CoreCLR用到的StackWakling技术,因为一个栈上的函数类型,可能有FCall、QCall以及CoreCLR本身的函数和IL编译成的函数,因此这部分会比较复杂。
2025-01-05 22:34:45
818
原创 CoreCLR 桩(Stub)的触发(2)
上一篇文章中描述了CLR中是如何通过precode来触发JIT的编译,这篇文章接着说JIT将IL代码编译机器码之后需要进行什么操作。这两篇文章说了CoreCLR中调用函数触发JIT编译以及编译之后的流程,通过这种方式来实现懒编译,即如果一个函数在程序里面不被调用,则不会被编译。若有错误请指正,有问题欢迎指出。
2024-10-14 21:57:58
1033
4
原创 CoreCLR 虚函数调用源码
本文讲一下CoreCLR中虚函数的存储方式, 以及如何调用一个虚函数,推荐先看BoTR中关于MethodDesc的描述,对MethodTable的结构有一个了解。需要注意的是本文所描述的源码是CoreCLR8.0.1版本。与CLR2.0的虚函数表结构有较大的差别。
2024-10-13 01:47:24
653
1
原创 CoreCLR 桩(Stub)的触发(1)
本篇文章主要描述CoreCLR中是如何触发JIT的编译,已经编译之后的流程。注意,这篇文章不讲述JIT的编译过程,我们只需知道JIT输入的是IL代码,输出机器码就够了。
2024-10-01 22:41:41
815
原创 CoreCLR 分配小对象内存
在这篇文章中,描述了清扫(sweep)阶段如何回收未存活对象所占用的内存,这篇文章着重描述如何分配创建一个小对象(small object, 下文都叫小对象)所需要的内存,利用清扫阶段回收的内存。
2024-09-26 22:36:47
845
原创 CoreCLR Sweep阶段源码分析
Sweep(清扫,下文都叫这个名字)阶段发生在Plan Phase(计划)阶段之后,其主要作用就是将未被标记存活的物体所占的内存回收起来,并创建自由列表。如果空间足够大可以作为之后分配内存使用。此次分析代码所使用的CoreCLR版本为 8.0。
2024-09-23 22:04:27
1204
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅