Fix disappearing labels in SurfaceFlinger rects view
Test: open SF trace, scroll back and forth in time, check that labels don't disappear Fix: b/254244305 Change-Id: I05129db8f5a7a5ee2dd42d7d685aac1588b8594c
This commit is contained in:
@@ -20,7 +20,7 @@ import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
|
||||
import { ViewerEvents } from "viewers/common/viewer_events";
|
||||
|
||||
export class CanvasGraphics {
|
||||
constructor() {
|
||||
constructor(canvasRects: HTMLCanvasElement, canvasLabels: HTMLElement) {
|
||||
//set up camera
|
||||
const left = -this.CAMERA_HALF_WIDTH,
|
||||
right = this.CAMERA_HALF_WIDTH,
|
||||
@@ -31,24 +31,21 @@ export class CanvasGraphics {
|
||||
this.camera = new THREE.OrthographicCamera(
|
||||
left, right, top, bottom, near, far
|
||||
);
|
||||
|
||||
this.canvasRects = canvasRects;
|
||||
this.canvasLabels = canvasLabels;
|
||||
|
||||
this.resetCamera();
|
||||
}
|
||||
|
||||
public initialiseCanvas(canvas: HTMLCanvasElement, canvasContainer: Element) {
|
||||
// initialise canvas
|
||||
this.canvas = canvas;
|
||||
this.canvasContainer = canvasContainer;
|
||||
this.enableOrbitControls();
|
||||
}
|
||||
|
||||
public refreshCanvas() {
|
||||
if (!this.canvas) {
|
||||
if (!this.canvasRects) {
|
||||
return;
|
||||
}
|
||||
|
||||
//set canvas size
|
||||
this.canvas.style.width = "100%";
|
||||
this.canvas.style.height = "100%";
|
||||
this.canvasRects.style.width = "100%";
|
||||
this.canvasRects.style.height = "100%";
|
||||
|
||||
this.orbit?.reset();
|
||||
|
||||
@@ -56,24 +53,11 @@ export class CanvasGraphics {
|
||||
|
||||
this.renderer = new THREE.WebGLRenderer({
|
||||
antialias: true,
|
||||
canvas: this.canvas,
|
||||
canvas: this.canvasRects,
|
||||
alpha: true
|
||||
});
|
||||
|
||||
if (this.canvasContainer && this.canvasContainer.querySelector(".labels-canvas")) {
|
||||
this.labelRenderer = new CSS2DRenderer({
|
||||
element: this.canvasContainer.querySelector(".labels-canvas")! as HTMLElement
|
||||
});
|
||||
} else {
|
||||
this.labelRenderer = new CSS2DRenderer();
|
||||
this.labelRenderer.domElement.style.position = "absolute";
|
||||
this.labelRenderer.domElement.style.top = "0px";
|
||||
this.labelRenderer.domElement.style.width = "100%";
|
||||
this.labelRenderer.domElement.style.height = "100%";
|
||||
this.labelRenderer.domElement.className = "labels-canvas";
|
||||
this.labelRenderer.domElement.style.pointerEvents = "none";
|
||||
this.canvasContainer?.appendChild(this.labelRenderer.domElement);
|
||||
}
|
||||
this.labelRenderer = new CSS2DRenderer({element: this.canvasLabels});
|
||||
|
||||
// set various factors for shading and shifting
|
||||
const numberOfRects = this.rects.length;
|
||||
@@ -108,17 +92,17 @@ export class CanvasGraphics {
|
||||
lowestY
|
||||
);
|
||||
|
||||
this.renderer.setSize(this.canvas!.clientWidth, this.canvas!.clientHeight);
|
||||
this.renderer.setSize(this.canvasRects!.clientWidth, this.canvasRects!.clientHeight);
|
||||
this.renderer.setPixelRatio(window.devicePixelRatio);
|
||||
this.renderer.compile(this.scene, this.camera);
|
||||
this.renderer.render(this.scene, this.camera);
|
||||
|
||||
this.labelRenderer.setSize(this.canvas!.clientWidth, this.canvas!.clientHeight);
|
||||
this.labelRenderer.setSize(this.canvasRects!.clientWidth, this.canvasRects!.clientHeight);
|
||||
this.labelRenderer.render(this.scene, this.camera);
|
||||
}
|
||||
|
||||
public enableOrbitControls() {
|
||||
this.orbit = new OrbitControls(this.camera, this.canvas);
|
||||
this.orbit = new OrbitControls(this.camera, this.canvasRects);
|
||||
this.orbit.enablePan = true;
|
||||
this.orbit.enableDamping = true;
|
||||
this.orbit.enableZoom = true;
|
||||
@@ -130,7 +114,7 @@ export class CanvasGraphics {
|
||||
this.fontSize = this.camera.zoom * this.INIT_FONT_SIZE;
|
||||
this.updateLabelsFontSize();
|
||||
if (this.scene && this.renderer && this.labelRenderer) {
|
||||
this.clearLabelElements();
|
||||
this.clearLabels();
|
||||
this.renderer.compile(this.scene, this.camera);
|
||||
this.renderer.render(this.scene, this.camera);
|
||||
this.labelRenderer.render(this.scene, this.camera);
|
||||
@@ -210,7 +194,7 @@ export class CanvasGraphics {
|
||||
this.lowestYShift = this.INIT_LOWEST_Y_SHIFT;
|
||||
this.layerSeparation = this.INIT_LAYER_SEPARATION;
|
||||
this.camera.updateProjectionMatrix();
|
||||
if (this.canvas) {
|
||||
if (this.canvasRects) {
|
||||
this.enableOrbitControls();
|
||||
}
|
||||
this.refreshCanvas();
|
||||
@@ -241,7 +225,7 @@ export class CanvasGraphics {
|
||||
lowestY: number
|
||||
) {
|
||||
this.targetObjects = [];
|
||||
this.clearLabelElements();
|
||||
this.clearLabels();
|
||||
|
||||
const darkFactors = this.computeRectDarkFactors(this.rects);
|
||||
|
||||
@@ -449,8 +433,8 @@ export class CanvasGraphics {
|
||||
);
|
||||
}
|
||||
|
||||
private clearLabelElements() {
|
||||
document.querySelectorAll(".rect-label").forEach(el => el.remove());
|
||||
private clearLabels() {
|
||||
this.canvasLabels.innerHTML = "";
|
||||
}
|
||||
|
||||
private shortenText(text: string): string {
|
||||
@@ -489,6 +473,6 @@ export class CanvasGraphics {
|
||||
private orbit?: OrbitControls;
|
||||
private rects: Rectangle[] = [];
|
||||
private targetObjects: any[] = [];
|
||||
private canvas?: HTMLCanvasElement;
|
||||
private canvasContainer?: Element;
|
||||
private canvasRects?: HTMLCanvasElement;
|
||||
private canvasLabels: HTMLElement;
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ describe("RectsComponent", () => {
|
||||
|
||||
it("renders rects canvas", () => {
|
||||
fixture.detectChanges();
|
||||
const rectsCanvas = htmlElement.querySelector(".rects-canvas");
|
||||
const rectsCanvas = htmlElement.querySelector(".canvas-rects");
|
||||
expect(rectsCanvas).toBeTruthy();
|
||||
});
|
||||
|
||||
|
||||
@@ -91,8 +91,10 @@ import { ViewerEvents } from "viewers/common/viewer_events";
|
||||
<mat-divider></mat-divider>
|
||||
<div class="rects-content">
|
||||
<div class="canvas-container">
|
||||
<canvas class="rects-canvas" (click)="onRectClick($event)" oncontextmenu="return false">
|
||||
<canvas class="canvas-rects" (click)="onRectClick($event)" oncontextmenu="return false">
|
||||
</canvas>
|
||||
<div class="canvas-labels">
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="displayIds.length > 1" class="display-button-container">
|
||||
<button
|
||||
@@ -142,11 +144,9 @@ import { ViewerEvents } from "viewers/common/viewer_events";
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
.labels-canvas, .rects-canvas {
|
||||
.canvas-rects {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
}
|
||||
.rects-canvas {
|
||||
cursor: pointer;
|
||||
}
|
||||
.display-button-container {
|
||||
@@ -155,6 +155,13 @@ import { ViewerEvents } from "viewers/common/viewer_events";
|
||||
flex-wrap: wrap;
|
||||
column-gap: 10px;
|
||||
}
|
||||
.canvas-labels {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
pointer-events: none;
|
||||
}
|
||||
`
|
||||
]
|
||||
})
|
||||
@@ -165,19 +172,21 @@ export class RectsComponent implements OnInit, OnChanges, OnDestroy {
|
||||
@Input() hasVirtualDisplays = false;
|
||||
@Input() displayIds: Array<number> = [];
|
||||
@Input() highlightedItems: Array<string> = [];
|
||||
canvasInitialised = false;
|
||||
rectsComponentInitialised = false;
|
||||
|
||||
constructor(
|
||||
@Inject(ElementRef) private elementRef: ElementRef,
|
||||
) {
|
||||
this.canvasGraphics = new CanvasGraphics();
|
||||
this.currentDisplayId = this.displayIds[0] ?? 0; // default stack id is usually zero
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.canvas = this.elementRef.nativeElement.querySelector("canvas")! as HTMLCanvasElement;
|
||||
this.canvasContainer = this.elementRef.nativeElement.querySelector(".canvas-container")!;
|
||||
this.canvasRects =
|
||||
this.elementRef.nativeElement.querySelector(".canvas-rects")! as HTMLCanvasElement;
|
||||
this.canvasLabels = this.elementRef.nativeElement.querySelector(".canvas-labels")!;
|
||||
|
||||
this.canvasGraphics = new CanvasGraphics(this.canvasRects, this.canvasLabels);
|
||||
|
||||
window.addEventListener("resize", () => this.refreshCanvas());
|
||||
this.addContainerResizeListener();
|
||||
@@ -200,7 +209,7 @@ export class RectsComponent implements OnInit, OnChanges, OnDestroy {
|
||||
}
|
||||
}
|
||||
if (changes["highlightedItems"]) {
|
||||
this.canvasGraphics.updateHighlightedItems(this.highlightedItems);
|
||||
this.canvasGraphics!.updateHighlightedItems(this.highlightedItems);
|
||||
}
|
||||
if (this.rects.length > 0 || changes["forceRefresh"]?.currentValue) {
|
||||
this.formatAndDrawRects(changes["rects"] !== undefined);
|
||||
@@ -213,49 +222,49 @@ export class RectsComponent implements OnInit, OnChanges, OnDestroy {
|
||||
}
|
||||
|
||||
public onChangeView(visible: boolean) {
|
||||
this.canvasGraphics.updateVisibleView(visible);
|
||||
this.canvasGraphics!.updateVisibleView(visible);
|
||||
this.refreshCanvas();
|
||||
}
|
||||
|
||||
public visibleView() {
|
||||
return this.canvasGraphics.getVisibleView();
|
||||
return this.canvasGraphics!.getVisibleView();
|
||||
}
|
||||
|
||||
public getLayerSeparation() {
|
||||
return this.canvasGraphics.getLayerSeparation();
|
||||
return this.canvasGraphics!.getLayerSeparation();
|
||||
}
|
||||
|
||||
public updateLayerSeparation(sep: number) {
|
||||
this.canvasGraphics.updateLayerSeparation(sep);
|
||||
this.canvasGraphics!.updateLayerSeparation(sep);
|
||||
this.refreshCanvas();
|
||||
}
|
||||
|
||||
public updateRotation(rot: number) {
|
||||
this.canvasGraphics.updateRotation(rot);
|
||||
this.canvasGraphics!.updateRotation(rot);
|
||||
this.refreshCanvas();
|
||||
}
|
||||
|
||||
public resetCamera() {
|
||||
this.canvasGraphics.resetCamera();
|
||||
this.canvasGraphics!.resetCamera();
|
||||
this.refreshCanvas();
|
||||
}
|
||||
|
||||
public updateZoom(zoom: boolean) {
|
||||
this.canvasGraphics.updateZoom(zoom);
|
||||
this.canvasGraphics!.updateZoom(zoom);
|
||||
this.refreshCanvas();
|
||||
}
|
||||
|
||||
public updateVirtualDisplays(show: boolean) {
|
||||
this.canvasGraphics.updateVirtualDisplays(show);
|
||||
this.canvasGraphics!.updateVirtualDisplays(show);
|
||||
this.refreshCanvas();
|
||||
}
|
||||
|
||||
public xCameraPos() {
|
||||
return this.canvasGraphics.getXCameraPos();
|
||||
return this.canvasGraphics!.getXCameraPos();
|
||||
}
|
||||
|
||||
public showVirtualDisplays() {
|
||||
return this.canvasGraphics.getShowVirtualDisplays();
|
||||
return this.canvasGraphics!.getShowVirtualDisplays();
|
||||
}
|
||||
|
||||
public changeDisplayId(displayId: number) {
|
||||
@@ -266,9 +275,9 @@ export class RectsComponent implements OnInit, OnChanges, OnDestroy {
|
||||
public onRectClick(event: MouseEvent) {
|
||||
this.setNormalisedMousePos(event);
|
||||
const raycaster = new THREE.Raycaster();
|
||||
raycaster.setFromCamera(this.mouse, this.canvasGraphics.getCamera());
|
||||
raycaster.setFromCamera(this.mouse, this.canvasGraphics!.getCamera());
|
||||
// create an array containing all objects in the scene with which the ray intersects
|
||||
const intersects = raycaster.intersectObjects(this.canvasGraphics.getTargetObjects());
|
||||
const intersects = raycaster.intersectObjects(this.canvasGraphics!.getTargetObjects());
|
||||
// if there is one (or more) intersections
|
||||
if (intersects.length > 0) {
|
||||
const id = intersects[0].object.name;
|
||||
@@ -277,11 +286,8 @@ export class RectsComponent implements OnInit, OnChanges, OnDestroy {
|
||||
}
|
||||
|
||||
public drawRects() {
|
||||
if (!this.canvasContainer || !this.canvas) {
|
||||
if (!this.canvasContainer || !this.canvasRects) {
|
||||
return;
|
||||
} else if (!this.canvasInitialised) {
|
||||
this.canvasGraphics.initialiseCanvas(this.canvas, this.canvasContainer);
|
||||
this.canvasInitialised = true;
|
||||
}
|
||||
this.refreshCanvas();
|
||||
}
|
||||
@@ -338,14 +344,14 @@ export class RectsComponent implements OnInit, OnChanges, OnDestroy {
|
||||
|
||||
public refreshCanvas() {
|
||||
this.updateVariablesBeforeRefresh();
|
||||
this.canvasGraphics.refreshCanvas();
|
||||
this.canvasGraphics!.refreshCanvas();
|
||||
}
|
||||
|
||||
private updateVariablesBeforeRefresh() {
|
||||
const rects = this.rects.filter(rect => rect.displayId === this.currentDisplayId);
|
||||
this.canvasGraphics.updateRects(rects);
|
||||
this.canvasGraphics!.updateRects(rects);
|
||||
const biggestX = Math.max(...this.rects.map(rect => rect.topLeft.x + rect.width/2));
|
||||
this.canvasGraphics.updateIsLandscape(biggestX > this.s({x: this.boundsWidth, y:this.boundsHeight}).x/2);
|
||||
this.canvasGraphics!.updateIsLandscape(biggestX > this.s({x: this.boundsWidth, y:this.boundsHeight}).x/2);
|
||||
}
|
||||
|
||||
private computeBounds(): any {
|
||||
@@ -382,9 +388,9 @@ export class RectsComponent implements OnInit, OnChanges, OnDestroy {
|
||||
private s(sourceCoordinates: Point): Point {
|
||||
let scale;
|
||||
if (this.boundsWidth < this.boundsHeight) {
|
||||
scale = this.canvasGraphics.CAMERA_HALF_HEIGHT * 2 * 0.6 / this.boundsHeight;
|
||||
scale = this.canvasGraphics!.CAMERA_HALF_HEIGHT * 2 * 0.6 / this.boundsHeight;
|
||||
} else {
|
||||
scale = this.canvasGraphics.CAMERA_HALF_WIDTH * 2 * 0.6 / this.boundsWidth;
|
||||
scale = this.canvasGraphics!.CAMERA_HALF_WIDTH * 2 * 0.6 / this.boundsWidth;
|
||||
}
|
||||
return {
|
||||
x: sourceCoordinates.x * scale,
|
||||
@@ -406,14 +412,14 @@ export class RectsComponent implements OnInit, OnChanges, OnDestroy {
|
||||
|
||||
private addContainerResizeListener() {
|
||||
this.resizeObserver = new ResizeObserver((entries) => {
|
||||
if (entries[0].contentRect.height > 0 && this.canvasInitialised) {
|
||||
if (entries[0].contentRect.height > 0) {
|
||||
this.refreshCanvas();
|
||||
}
|
||||
});
|
||||
this.resizeObserver.observe(this.canvasContainer!);
|
||||
}
|
||||
|
||||
private canvasGraphics: CanvasGraphics;
|
||||
private canvasGraphics?: CanvasGraphics;
|
||||
private boundsWidth = 0;
|
||||
private boundsHeight = 0;
|
||||
private displayRects!: Rectangle[];
|
||||
@@ -421,5 +427,6 @@ export class RectsComponent implements OnInit, OnChanges, OnDestroy {
|
||||
private currentDisplayId: number;
|
||||
private resizeObserver!: ResizeObserver;
|
||||
private canvasContainer!: Element;
|
||||
private canvas!: HTMLCanvasElement;
|
||||
private canvasRects!: HTMLCanvasElement;
|
||||
private canvasLabels!: HTMLElement;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user