Skip to content

Commit

Permalink
node related optimizations (cocos#8716)
Browse files Browse the repository at this point in the history
* opt: node.invalidateChildren

* opt: cache pass states

* make hasChangedFlags visible to native

* fix switch case indent rule
YunHsiao authored May 27, 2021
1 parent d8890c5 commit 0fc8e6f
Showing 11 changed files with 196 additions and 135 deletions.
6 changes: 5 additions & 1 deletion .eslintrc.yaml
Original file line number Diff line number Diff line change
@@ -71,7 +71,8 @@ rules:
import/extensions: off # typescript doesn't support this
import/no-unresolved: off # TODO: fix internal modules
import/prefer-default-export: off # prefer named exports
indent: [warn, 4] # we use 4-space convention
indent: off # use @typescript-eslint/indent instead for better compatibility

lines-between-class-members: off # be more lenient on member declarations
max-classes-per-file: off # helper classes are common
max-len: [warn, 150] # more lenient on max length per line
@@ -96,6 +97,9 @@ rules:

##### TYPESCRIPT-SPECIFIC RULE OVERRIDES #####

'@typescript-eslint/indent': [warn, 4, {
SwitchCase: 0
}]
'@typescript-eslint/no-unused-expressions': warn

# TODO: this is just too much work
2 changes: 1 addition & 1 deletion cocos/core/director.ts
Original file line number Diff line number Diff line change
@@ -906,7 +906,7 @@ export class Director extends EventTarget {
this.emit(Director.EVENT_AFTER_DRAW);

eventManager.frameUpdateListeners();
Node.clearBooks();
Node.resetHasChangedFlags();
this._totalFrames++;
}
}
1 change: 0 additions & 1 deletion cocos/core/gfx/index.jsb.ts
Original file line number Diff line number Diff line change
@@ -68,7 +68,6 @@ polyfillCC.CommandBuffer = gfx.CommandBuffer;
polyfillCC.Queue = gfx.Queue;
legacyCC.gfx = polyfillCC;

export const Attribute = gfx.Attribute;
// TODO: remove these after state info refactor
export const BlendTarget = pso.BlendTarget;
export const BlendState = pso.BlendState;
10 changes: 3 additions & 7 deletions cocos/core/pipeline/pipeline-state-manager.ts
Original file line number Diff line number Diff line change
@@ -29,32 +29,28 @@
*/

import { Shader, RenderPass, InputAssembler, Device, PipelineState, InputState, PipelineStateInfo } from '../gfx';
import { PassPool, PassView, PassHandle, PipelineLayoutPool } from '../renderer/core/memory-pools';
import { Pass } from '../renderer/core/pass';

export class PipelineStateManager {
private static _PSOHashMap: Map<number, PipelineState> = new Map<number, PipelineState>();

// pass is only needed on TS.
static getOrCreatePipelineState (device: Device, pass: Pass, shader: Shader, renderPass: RenderPass, ia: InputAssembler) {
const hPass = pass.handle;
const hash1 = PassPool.get(hPass, PassView.HASH);
const hash1 = pass.hash;
const hash2 = renderPass.hash;
const hash3 = ia.attributesHash;
const hash4 = shader.id;

const newHash = hash1 ^ hash2 ^ hash3 ^ hash4;
let pso = this._PSOHashMap.get(newHash);
if (!pso) {
const pipelineLayout = PipelineLayoutPool.get(PassPool.get(hPass, PassView.PIPELINE_LAYOUT));
const inputState = new InputState(ia.attributes);
const psoInfo = new PipelineStateInfo(
shader, pipelineLayout, renderPass, inputState,
shader, pass.pipelineLayout, renderPass, inputState,
pass.rasterizerState,
pass.depthStencilState,
pass.blendState,
PassPool.get(hPass, PassView.PRIMITIVE),
PassPool.get(hPass, PassView.DYNAMIC_STATES),
pass.primitive, pass.dynamicStates,
);
pso = device.createPipelineState(psoInfo);
this._PSOHashMap.set(newHash, pso);
10 changes: 5 additions & 5 deletions cocos/core/pipeline/render-queue.ts
Original file line number Diff line number Diff line change
@@ -33,7 +33,7 @@ import { CachedArray } from '../memop/cached-array';
import { IRenderObject, IRenderPass, IRenderQueueDesc, SetIndex } from './define';
import { PipelineStateManager } from './pipeline-state-manager';
import { RenderPass, Device, CommandBuffer } from '../gfx';
import { PassPool, PassView, DSPool, SubModelView, SubModelPool, ShaderPool, PassHandle, ShaderHandle } from '../renderer/core/memory-pools';
import { SubModelView, SubModelPool, ShaderPool, ShaderHandle } from '../renderer/core/memory-pools';
import { RenderQueueDesc, RenderQueueSortMode } from './pipeline-serialization';
import { getPhaseID } from './pass-phase';

@@ -103,12 +103,12 @@ export class RenderQueue {
*/
public insertRenderPass (renderObj: IRenderObject, subModelIdx: number, passIdx: number): boolean {
const subModel = renderObj.model.subModels[subModelIdx];
const hPass = SubModelPool.get(subModel.handle, SubModelView.PASS_0 + passIdx) as PassHandle;
const isTransparent = subModel.passes[passIdx].blendState.targets[0].blend;
if (isTransparent !== this._passDesc.isTransparent || !(PassPool.get(hPass, PassView.PHASE) & this._passDesc.phases)) {
const pass = subModel.passes[passIdx];
const isTransparent = pass.blendState.targets[0].blend;
if (isTransparent !== this._passDesc.isTransparent || !(pass.phase & this._passDesc.phases)) {
return false;
}
const hash = (0 << 30) | PassPool.get(hPass, PassView.PRIORITY) << 16 | subModel.priority << 8 | passIdx;
const hash = (0 << 30) | pass.priority << 16 | subModel.priority << 8 | passIdx;
const rp = this._passPool.add();
rp.hash = hash;
rp.depth = renderObj.depth || 0;
5 changes: 3 additions & 2 deletions cocos/core/pipeline/scene-culling.ts
Original file line number Diff line number Diff line change
@@ -222,14 +222,15 @@ export function sceneCulling (pipeline: RenderPipeline, camera: Camera) {
}

const models = scene.models;
const visibility = camera.visibility;

for (let i = 0; i < models.length; i++) {
const model = models[i];

// filter model by view visibility
if (model.enabled) {
if (model.node && ((camera.visibility & model.node.layer) === model.node.layer)
|| (camera.visibility & model.visFlags)) {
if (model.node && ((visibility & model.node.layer) === model.node.layer)
|| (visibility & model.visFlags)) {
// shadow render Object
if (shadowObjects != null && model.castShadow && model.worldBounds) {
if (!_castBoundsInited) {
6 changes: 3 additions & 3 deletions cocos/core/renderer/core/memory-pools.ts
Original file line number Diff line number Diff line change
@@ -1062,7 +1062,7 @@ const cameraViewDataType: BufferDataTypeManifest<typeof CameraView> = {
export const CameraPool = new BufferPool<PoolType.CAMERA, typeof CameraView, ICameraViewType>(PoolType.CAMERA, cameraViewDataType, CameraView);

export enum NodeView {
FLAGS_CHANGED,
HAS_CHANGED_FLAGS,
LAYER,
WORLD_SCALE, // Vec3
WORLD_POSITION = 5, // Vec3
@@ -1071,7 +1071,7 @@ export enum NodeView {
COUNT = 28
}
interface INodeViewType extends BufferTypeManifest<typeof NodeView> {
[NodeView.FLAGS_CHANGED]: number;
[NodeView.HAS_CHANGED_FLAGS]: number;
[NodeView.LAYER]: number;
[NodeView.WORLD_SCALE]: Vec3;
[NodeView.WORLD_POSITION]: Vec3;
@@ -1080,7 +1080,7 @@ interface INodeViewType extends BufferTypeManifest<typeof NodeView> {
[NodeView.COUNT]: never;
}
const nodeViewDataType: BufferDataTypeManifest<typeof NodeView> = {
[NodeView.FLAGS_CHANGED]: BufferDataType.UINT32,
[NodeView.HAS_CHANGED_FLAGS]: BufferDataType.UINT32,
[NodeView.LAYER]: BufferDataType.UINT32,
[NodeView.WORLD_SCALE]: BufferDataType.FLOAT32,
[NodeView.WORLD_POSITION]: BufferDataType.FLOAT32,
4 changes: 2 additions & 2 deletions cocos/core/renderer/core/pass-instance.ts
Original file line number Diff line number Diff line change
@@ -122,11 +122,11 @@ export class PassInstance extends Pass {

protected _syncBatchingScheme () {
this._defines.USE_BATCHING = this._defines.USE_INSTANCING = false;
PassPool.set(this._handle, PassView.BATCHING_SCHEME, 0);
this.batchingScheme = 0;
}

protected _onStateChange () {
PassPool.set(this._handle, PassView.HASH, Pass.getPassHash(this, this._hShaderDefault));
this.hash = Pass.getPassHash(this, this._hShaderDefault);
this._owner.onPassStateChange(this._dontNotify);
}
}
Loading

0 comments on commit 0fc8e6f

Please sign in to comment.