Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(render-engine): move cache to viewport #2188

Merged
merged 13 commits into from
May 25, 2024
26 changes: 26 additions & 0 deletions packages/core/src/shared/rectangle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -283,4 +283,30 @@ export class Rectangle {

return result;
}

static hasIntersectionBetweenTwoBounds(
rect1: {
left: number;
top: number;
right: number;
bottom: number;
},
rect2: {
left: number;
top: number;
right: number;
bottom: number;
}
) {
if (
rect1.left > rect2.right || // rect1 在 rect2 右侧
rect1.right < rect2.left || // rect1 在 rect2 左侧
rect1.top > rect2.bottom || // rect1 在 rect2 下方
rect1.bottom < rect2.top // rect1 在 rect2 上方
) {
return false;
}

return true;
}
}
2 changes: 2 additions & 0 deletions packages/docs-ui/src/views/doc-canvas-view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ export class DocCanvasView extends RxDisposable {
top: 0,
bottom: 0,
right: 0,
isRelativeX: true,
isRelativeY: true,
isWheelPreventDefaultX: true,
});

Expand Down
11 changes: 8 additions & 3 deletions packages/engine-render/src/base-object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import type { IObjectFullState, ITransformChangeState } from './basics/interface
import { TRANSFORM_CHANGE_OBSERVABLE_TYPE } from './basics/interfaces';
import { generateRandomKey, toPx } from './basics/tools';
import { Transform } from './basics/transform';
import type { IViewportBound, Vector2 } from './basics/vector2';
import type { IViewportInfo, Vector2 } from './basics/vector2';
import type { UniverRenderingContext } from './context';
import type { Layer } from './layer';

Expand Down Expand Up @@ -87,6 +87,7 @@ export abstract class BaseObject extends Disposable {
protected _oKey: string;

protected _dirty: boolean = true;
protected _forceDirty: boolean = true;

private _top: number = 0;

Expand Down Expand Up @@ -367,6 +368,10 @@ export abstract class BaseObject extends Disposable {
return this;
}

makeForceDirty(state: boolean = true) {
this._forceDirty = state;
}

makeDirtyNoDebounce(state: boolean = true) {
this._dirty = state;
if (state) {
Expand Down Expand Up @@ -514,7 +519,7 @@ export abstract class BaseObject extends Disposable {
return this;
}

isRender(bounds?: IViewportBound) {
isRender(bounds?: IViewportInfo) {
if (this._forceRender) {
return false;
}
Expand Down Expand Up @@ -551,7 +556,7 @@ export abstract class BaseObject extends Disposable {
this._makeDirtyMix();
}

render(ctx: UniverRenderingContext, bounds?: IViewportBound) {
render(ctx: UniverRenderingContext, bounds?: IViewportInfo) {
/* abstract */
}

Expand Down
78 changes: 77 additions & 1 deletion packages/engine-render/src/basics/tools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import type {
LocaleService,
Nullable,
} from '@univerjs/core';
import { BaselineOffset, DEFAULT_STYLES, FontStyleType, Tools } from '@univerjs/core';
import { BaselineOffset, DEFAULT_STYLES, FontStyleType, Rectangle, Tools } from '@univerjs/core';
import * as cjk from 'cjk-regex';

import { FontCache } from '../components/docs/layout/shaping-engine/font-cache';
Expand Down Expand Up @@ -757,3 +757,79 @@ export function ptToPixel(pt: number) {
export function pixelToPt(px: number) {
return px * PX_TO_PT_RATIO;
}

/**
* 当前单元格在任意一个 viewRanges 中
* @param ranges
* @param rowIndex
* @param colIndex
* @returns
*/
export function inViewRanges(ranges: IRange[], rowIndex: number, colIndex: number) {
for (const range of ranges) {
if (rowIndex >= range.startRow && rowIndex <= range.endRow &&
colIndex >= range.startColumn && colIndex <= range.endColumn) {
return true;
}
}
return false;
}

/**
* 在非下方区域中
* @param ranges
* @param rowIndex
* @returns
*/
export function inCurrentAndAboveViewRanges(ranges: IRange[], rowIndex: number) {
for (const range of ranges) {
if (rowIndex > range.endRow) {
return false;
}
}
return true;
}

/**
* row 在任意一个 Range 中
* @param ranges
* @param rowIndex
* @returns
*/
export function inRowViewRanges(ranges: IRange[], rowIndex: number) {
let flag = false;
for (const range of ranges) {
if (rowIndex >= range.startRow && rowIndex <= range.endRow) {
flag = true;
break;
}
}
return flag;
}

/**
* 如果 range 有相交, 那么扩展到第一组 range 中.
* @param ranges
*/
export function mergeRangeIfIntersects(mainRanges: IRange[], ranges: IRange[]) {
for (const mainRange of mainRanges) {
for (const range of ranges) {
if (Rectangle.intersects(mainRange, range)) {
mainRange.startRow = Math.min(mainRange.startRow, range.startRow);
mainRange.endRow = Math.max(mainRange.endRow, range.endRow);
mainRange.startColumn = Math.min(mainRange.startColumn, range.startColumn);
mainRange.endColumn = Math.max(mainRange.endColumn, range.endColumn);
}
}
}
return mainRanges;
}

export function clampRanges(range: IRange) {
return {
startRow: Math.max(0, range.startRow),
startColumn: Math.max(0, range.startColumn),
endRow: Math.max(0, range.endRow),
endColumn: Math.max(0, range.endColumn),
};
}
14 changes: 14 additions & 0 deletions packages/engine-render/src/basics/transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ export class Transform {
this._m[1] *= sx;
this._m[2] *= sy;
this._m[3] *= sy;
this._m[4] *= sx;
this._m[5] *= sy;
return this;
}

Expand Down Expand Up @@ -387,6 +389,18 @@ export class Transform {
return scaleMatrix;
}

convert2DOMMatrix2D() {
const m = this.getMatrix();
return {
a: m[0],
b: m[1],
c: m[2],
d: m[3],
e: m[4],
f: m[5],
};
}

// static createTransformByState(state: positionState) {
// const newTr = new this();
// let { x, y, angle, scaleX, scaleY, skewX, skewY, flipX, flipY } = state;
Expand Down
54 changes: 52 additions & 2 deletions packages/engine-render/src/basics/vector2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@
* limitations under the License.
*/

import type { Canvas } from '../canvas';
import type { SHEET_VIEWPORT_KEY } from '../components/sheets/interfaces';
import type { DeepImmutable, FloatArray } from './i-events';
import type { Transform } from './transform';

export interface IPoint {
x: number;
Expand Down Expand Up @@ -844,17 +847,64 @@ export interface IBoundRect {
}

export interface IBoundRectNoAngle {
/**
* 冻结区域相对 MainCanvas 的物理位置,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

English prefer

* left = n * colWidth + rowHeaderWidth
*/
left: number;
top: number;
right: number;
bottom: number;
}

export interface IViewportBound {
export interface IViewportInfo {
viewBound: IBoundRectNoAngle;
diffBounds: IBoundRectNoAngle[];

/**
* scroll right further diffX < 0
* previewBound.x - viewbound.x
*/
diffX: number;
diffY: number;

/**
* The physical position of the frozen rows and columns on the canvas, used for drawImage.
* For example, if the freezing starts from the fourth column, the left position would be 4 * column + rowHeaderWidth.
* The physical position means the top and left values have already considered the scaling factor.
*/
viewPortPosition: IBoundRectNoAngle;
viewPortKey?: string;
viewportKey: string | SHEET_VIEWPORT_KEY;
/**
* In the future, a number will be used to indicate the reason for the "dirty" status
* Here, a binary value is used to facilitate computation.
*/
isDirty?: number;
isForceDirty?: boolean;

allowCache?: boolean;
cacheBound: IBoundRectNoAngle;
diffCacheBounds: IBoundRectNoAngle[];
cacheViewPortPosition: IBoundRectNoAngle;

shouldCacheUpdate: number;
sceneTrans: Transform;
cacheCanvas?: Canvas;

leftOrigin: number;
topOrigin: number;

bufferEdgeX: number;
bufferEdgeY: number;

updatePrevCacheBounds?: (viewbound: IBoundRectNoAngle) => void;
}

export interface IViewportInfos {
left: number;
right: number;
top: number;
bottom: number;
width: number;
height: number;
}
21 changes: 9 additions & 12 deletions packages/engine-render/src/canvas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,21 +130,18 @@ export class Canvas {
// this.setWidth(width || 0);
// this.setHeight(height || 0);
this._pixelRatio = pixelRatioParam || getDevicePixelRatio();
const canvsElement = this.getCanvasEle();

if (width) {
this.getCanvasEle().width = width * this._pixelRatio;

this._width = this.getCanvasEle().width / this._pixelRatio;

this.getCanvasEle().style.width = `${this._width}px`;
if (canvsElement && width !== undefined) {
canvsElement.width = width * this._pixelRatio;
this._width = canvsElement.width / this._pixelRatio;
canvsElement.style.width = `${this._width}px`;
}

if (height) {
this.getCanvasEle().height = height * this._pixelRatio;

this._height = this.getCanvasEle().height / this._pixelRatio;

this.getCanvasEle().style.height = `${this._height}px`;
if (canvsElement && height !== undefined) {
canvsElement.height = height * this._pixelRatio;
this._height = canvsElement.height / this._pixelRatio;
canvsElement.style.height = `${this._height}px`;
}

this.getContext().setTransform(this._pixelRatio, 0, 0, this._pixelRatio, 0, 0);
Expand Down
4 changes: 2 additions & 2 deletions packages/engine-render/src/components/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import { DisposableCollection, sortRules, toDisposable } from '@univerjs/core';
import type { IDisposable } from '@wendellhu/redi';
import { BaseObject } from '../base-object';
import type { IViewportBound } from '../basics/vector2';
import type { IViewportInfo } from '../basics/vector2';
import type { UniverRenderingContext } from '../context';
import type { ComponentExtension } from './extension';

Expand Down Expand Up @@ -58,7 +58,7 @@ export class RenderComponent<T, U, V> extends BaseObject {
return this._extensions.get(uKey);
}

draw(ctx: UniverRenderingContext, bounds?: IViewportBound) {
draw(ctx: UniverRenderingContext, bounds?: IViewportInfo) {
/* abstract */
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

import type { IViewportBound } from '../../basics/vector2';
import type { IViewportInfo } from '../../basics/vector2';
import type { UniverRenderingContext } from '../../context';
import { Rect } from '../../shape';
import { Liquid } from './liquid';
Expand All @@ -40,7 +40,7 @@ export class DocBackground extends DocComponent {
return new DocBackground(oKey, documentSkeleton, config);
}

override draw(ctx: UniverRenderingContext, bounds?: IViewportBound) {
override draw(ctx: UniverRenderingContext, bounds?: IViewportInfo) {
const skeletonData = this.getSkeleton()?.getSkeletonData();

if (skeletonData == null) {
Expand Down Expand Up @@ -103,7 +103,7 @@ export class DocBackground extends DocComponent {
return this;
}

protected override _draw(ctx: UniverRenderingContext, bounds?: IViewportBound) {
protected override _draw(ctx: UniverRenderingContext, bounds?: IViewportInfo) {
this.draw(ctx, bounds);
}
}
8 changes: 4 additions & 4 deletions packages/engine-render/src/components/docs/doc-component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import { RENDER_CLASS_TYPE } from '../../basics/const';
import type { IDocumentSkeletonGlyph, IDocumentSkeletonLine, IDocumentSkeletonPage } from '../../basics/i-document-skeleton-cached';
import { PageLayoutType } from '../../basics/i-document-skeleton-cached';
import type { IBoundRectNoAngle, IViewportBound } from '../../basics/vector2';
import type { IBoundRectNoAngle, IViewportInfo } from '../../basics/vector2';
import type { UniverRenderingContext } from '../../context';
import { RenderComponent } from '../component';
import type { DOCS_EXTENSION_TYPE } from './doc-extension';
Expand Down Expand Up @@ -82,7 +82,7 @@ export abstract class DocComponent extends RenderComponent<
}
}

override render(mainCtx: UniverRenderingContext, bounds?: IViewportBound) {
override render(mainCtx: UniverRenderingContext, bounds?: IViewportInfo) {
if (!this.visible) {
this.makeDirty(false);
return this;
Expand Down Expand Up @@ -118,7 +118,7 @@ export abstract class DocComponent extends RenderComponent<
};
}

isSkipByDiffBounds(page: IDocumentSkeletonPage, pageTop: number, pageLeft: number, bounds?: IViewportBound) {
isSkipByDiffBounds(page: IDocumentSkeletonPage, pageTop: number, pageLeft: number, bounds?: IViewportInfo) {
if (bounds === null || bounds === undefined) {
return false;
}
Expand Down Expand Up @@ -146,5 +146,5 @@ export abstract class DocComponent extends RenderComponent<
return false;
}

protected abstract _draw(ctx: UniverRenderingContext, bounds?: IViewportBound): void;
protected abstract _draw(ctx: UniverRenderingContext, bounds?: IViewportInfo): void;
}
Loading
Loading