gpu-trace-perf 1.8.2

Plays a collection of GPU traces under different environments to evaluate driver changes on performance
Documentation
<!-- Common scripts for CI dashboard -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
<script type="module">
    import PhotoSwipeLightbox from 'https://cdn.jsdelivr.net/npm/photoswipe@5.3.8/dist/photoswipe-lightbox.esm.js'
    import PhotoSwipe from 'https://cdn.jsdelivr.net/npm/photoswipe@5.3.8/dist/photoswipe.esm.js'

    const lightbox = new PhotoSwipeLightbox({
        gallery: `body`,
        children: 'a[id^="gallery-img"]',
        pswpModule: PhotoSwipe
    });
    lightbox.init();

    // Magnifying glass functionality
    document.addEventListener('DOMContentLoaded', function () {
        const magnifierContainer = document.querySelector('.magnifier-container');
        const magOriginal = document.getElementById('mag-original');
        const magDiff = document.getElementById('mag-diff');
        const magSecond = document.getElementById('mag-second');
        let ZOOM_LEVEL = 3.5;
        const MIN_ZOOM = 3;
        const MAX_ZOOM = 25;
        const ZOOM_STEP = 0.5;
        let isImagesSwapped = false;
        let activePreviewImg = null;
        let activeOriginalUrl = null;
        let activeDiffUrl = null;
        let activeRunAComment = null;
        let activeRunBComment = null;

        // Current magnifier position state, updated on mousemove
        let magState = null;

        // Set src on a magnifier img and track its load state directly on the element.
        // img._loadState: 'loading' | 'loaded' | 'error'
        function setMagnifierSrc(img, url) {
            if (img._trackedUrl === url) return;
            img._trackedUrl = url;
            img._loadState = 'loading';
            img.onload = () => {
                if (img._trackedUrl === url) {
                    img._loadState = 'loaded';
                    if (magnifierContainer.style.display === 'flex') {
                        renderMagnifierImages();
                    }
                }
            };
            img.onerror = () => {
                if (img._trackedUrl === url) {
                    img._loadState = 'error';
                    if (magnifierContainer.style.display === 'flex') {
                        renderMagnifierImages();
                    }
                }
            };
            img.src = url;
            // If browser served it synchronously from cache, complete is already true
            if (img.complete) {
                img._loadState = img.naturalWidth > 0 ? 'loaded' : 'error';
            }
        }

        function renderMagnifierImages() {
            if (!magState) return;
            const { xPercent, yPercent, rect, originalUrl, original2Url, diffUrl } = magState;

            [magOriginal, magDiff, magSecond].forEach((img, idx) => {
                let url;
                if (idx === 0) {
                    url = isImagesSwapped ? original2Url : originalUrl;
                } else if (idx === 1) {
                    url = diffUrl;
                } else {
                    url = isImagesSwapped ? originalUrl : original2Url;
                }

                setMagnifierSrc(img, url);

                const zoomedWidth = rect.width * ZOOM_LEVEL;
                const zoomedHeight = rect.height * ZOOM_LEVEL;
                img.style.width = zoomedWidth + 'px';
                img.style.height = zoomedHeight + 'px';
                const magnifierView = img.closest('.magnifier-view');
                const containerWidth = magnifierView.clientWidth;
                const containerHeight = magnifierView.clientHeight;
                // Center the cursor position in the magnifier view, clamped to image bounds
                img.style.left = `${Math.min(0, Math.max(-(zoomedWidth - containerWidth), containerWidth / 2 - xPercent * zoomedWidth))}px`;
                img.style.top = `${Math.min(0, Math.max(-(zoomedHeight - containerHeight), containerHeight / 2 - yPercent * zoomedHeight))}px`;

                const state = img._loadState || 'loading';
                img.style.visibility = (state === 'loaded') ? 'visible' : 'hidden';

                const label = magnifierView.querySelector('.magnifier-label');
                let baseText;
                if (idx === 0) {
                    baseText = isImagesSwapped ? `Run B${activeRunBComment ? ` - ${activeRunBComment}` : ''}` : `Run A${activeRunAComment ? ` - ${activeRunAComment}` : ''}`;
                } else if (idx === 1) {
                    baseText = 'Diff';
                } else {
                    baseText = isImagesSwapped ? `Run A${activeRunAComment ? ` - ${activeRunAComment}` : ''}` : `Run B${activeRunBComment ? ` - ${activeRunBComment}` : ''}`;
                }
                if (state === 'loading') {
                    label.textContent = `${baseText} - Loading...`;
                } else if (state === 'error') {
                    label.textContent = `${baseText} - Load failed`;
                } else {
                    label.textContent = `${baseText} - ${ZOOM_LEVEL}x`;
                }
            });
        }

        function updateMagnifier(e, container, originalUrl, original2Url, diffUrl) {
            const rect = container.getBoundingClientRect();
            const x = e.clientX - rect.left;
            const y = e.clientY - rect.top;

            magnifierContainer.style.display = 'flex';
            magState = {
                xPercent: x / rect.width,
                yPercent: y / rect.height,
                rect,
                originalUrl,
                original2Url,
                diffUrl,
            };
            renderMagnifierImages();
        }

        // Handle zoom with Ctrl+mousewheel
        function handleZoom(e) {
            if (e.ctrlKey) {
                e.preventDefault(); // Prevent page zoom
                const delta = Math.sign(e.deltaY) * -ZOOM_STEP;
                const newZoom = Math.max(MIN_ZOOM, Math.min(MAX_ZOOM, ZOOM_LEVEL + delta));

                if (newZoom !== ZOOM_LEVEL) {
                    ZOOM_LEVEL = newZoom;
                    // Trigger mousemove to update the display
                    const mousemoveEvent = new MouseEvent('mousemove', {
                        clientX: e.clientX,
                        clientY: e.clientY,
                        bubbles: true
                    });
                    e.target.dispatchEvent(mousemoveEvent);
                }
            }
        }

        // Add mouse events to image containers
        document.querySelectorAll('[id^="capture-"]').forEach(container => {
            const originalUrl = container.dataset.original;
            const original2Url = container.dataset.original2;
            const diffUrl = container.dataset.diff;
            const runAComment = container.dataset.runAComment;
            const runBComment = container.dataset.runBComment;

            if (originalUrl && diffUrl != "None") {
                container.querySelectorAll('.preview-image').forEach(previewImg => {
                    previewImg.addEventListener('mousemove', (e) => {
                        activePreviewImg = previewImg;
                        activeOriginalUrl = originalUrl;
                        activeDiffUrl = diffUrl;
                        activeRunAComment = runAComment;
                        activeRunBComment = runBComment;
                        updateMagnifier(e, previewImg, originalUrl, original2Url, diffUrl);
                    });

                    previewImg.addEventListener('wheel', handleZoom);

                    previewImg.addEventListener('mouseleave', () => {
                        magnifierContainer.style.display = 'none';
                        activePreviewImg = null;
                        activeOriginalUrl = null;
                        activeDiffUrl = null;
                        activeRunAComment = null;
                        activeRunBComment = null;
                    });
                });
            }
        });

        // Global space key handler for image swapping
        document.addEventListener('keydown', (e) => {
            if (e.code === 'Space' && magnifierContainer.style.display === 'flex' && activePreviewImg) {
                e.preventDefault(); // Prevent page scroll
                isImagesSwapped = !isImagesSwapped;
                renderMagnifierImages();
            }
        });
    });
</script>