@@ -1,5 +1,9 @@
|
||||
## [Unreleased]
|
||||
|
||||
### Fixed
|
||||
|
||||
* Fixed rendering issues when switching between screens w/ different `devicePixelRatios` [#147]
|
||||
|
||||
## [0.7.1] - 2018-08-20
|
||||
|
||||
### Fixed
|
||||
|
||||
@@ -49,7 +49,7 @@ export class CanvasContext {
|
||||
}
|
||||
private onBeforeFrame = () => {
|
||||
this.animationFrameRequest = null
|
||||
this.gl.setViewport(0, 0, this.gl.renderTargetWidth, this.gl.renderTargetHeight)
|
||||
this.gl.setViewport(0, 0, this.gl.renderTargetWidthInPixels, this.gl.renderTargetHeightInPixels)
|
||||
this.gl.clear(new Graphics.Color(1, 1, 1, 1))
|
||||
|
||||
for (const handler of this.beforeFrameHandlers) {
|
||||
|
||||
+21
-9
@@ -141,11 +141,11 @@ export namespace Graphics {
|
||||
abstract setRenderTarget(renderTarget: RenderTarget | null): void
|
||||
abstract setViewport(x: number, y: number, width: number, height: number): void
|
||||
abstract viewport: Rect
|
||||
abstract width: number
|
||||
abstract height: number
|
||||
abstract widthInPixels: number
|
||||
abstract heightInPixels: number
|
||||
|
||||
abstract renderTargetHeight: number
|
||||
abstract renderTargetWidth: number
|
||||
abstract renderTargetHeightInPixels: number
|
||||
abstract renderTargetWidthInPixels: number
|
||||
|
||||
abstract setBlendState(source: BlendOperation, target: BlendOperation): void
|
||||
setCopyBlendState() {
|
||||
@@ -304,10 +304,10 @@ export namespace WebGL {
|
||||
private _oldViewport = new Graphics.Rect()
|
||||
private _width = 0
|
||||
|
||||
get width() {
|
||||
get widthInPixels() {
|
||||
return this._width
|
||||
}
|
||||
get height() {
|
||||
get heightInPixels() {
|
||||
return this._height
|
||||
}
|
||||
|
||||
@@ -411,13 +411,13 @@ export namespace WebGL {
|
||||
: this._defaultViewport
|
||||
}
|
||||
|
||||
get renderTargetWidth() {
|
||||
get renderTargetWidthInPixels() {
|
||||
return this._currentRenderTarget != null
|
||||
? this._currentRenderTarget.viewport.width
|
||||
: this._width
|
||||
}
|
||||
|
||||
get renderTargetHeight() {
|
||||
get renderTargetHeightInPixels() {
|
||||
return this._currentRenderTarget != null
|
||||
? this._currentRenderTarget.viewport.height
|
||||
: this._height
|
||||
@@ -455,6 +455,18 @@ export namespace WebGL {
|
||||
widthInAppUnits: number,
|
||||
heightInAppUnits: number,
|
||||
) {
|
||||
const bounds = this._gl.canvas.getBoundingClientRect()
|
||||
|
||||
if (
|
||||
this._width === widthInAppUnits &&
|
||||
this._height === heightInPixels &&
|
||||
bounds.width === widthInAppUnits &&
|
||||
bounds.height === heightInAppUnits
|
||||
) {
|
||||
// Nothing to do here!
|
||||
return
|
||||
}
|
||||
|
||||
let canvas = this._gl.canvas
|
||||
let style = canvas.style
|
||||
canvas.width = widthInPixels
|
||||
@@ -547,7 +559,7 @@ export namespace WebGL {
|
||||
if (this._forceStateUpdate || !this._oldViewport.equals(viewport)) {
|
||||
gl.viewport(
|
||||
viewport.x,
|
||||
this.renderTargetHeight - viewport.y - viewport.height,
|
||||
this.renderTargetHeightInPixels - viewport.y - viewport.height,
|
||||
viewport.width,
|
||||
viewport.height,
|
||||
)
|
||||
|
||||
@@ -92,7 +92,7 @@ export class ViewportRectangleRenderer {
|
||||
this.material.setUniformVec2('physicalOrigin', viewport.x, viewport.y)
|
||||
this.material.setUniformVec2('physicalSize', viewport.width, viewport.height)
|
||||
|
||||
this.material.setUniformFloat('framebufferHeight', this.gl.renderTargetHeight)
|
||||
this.material.setUniformFloat('framebufferHeight', this.gl.renderTargetHeightInPixels)
|
||||
|
||||
this.gl.setBlendState(
|
||||
Graphics.BlendOperation.SOURCE_ALPHA,
|
||||
|
||||
@@ -43,6 +43,7 @@ export const ApplicationContainer = createContainer(
|
||||
return {
|
||||
activeProfileState,
|
||||
dispatch,
|
||||
canvasContext: state.glCanvas ? getCanvasContext(state.glCanvas) : null,
|
||||
resizeCanvas: (
|
||||
widthInPixels: number,
|
||||
heightInPixels: number,
|
||||
|
||||
+36
-20
@@ -12,6 +12,7 @@ import {StatelessComponent} from '../lib/typed-redux'
|
||||
import {LeftHeavyFlamechartView, ChronoFlamechartView} from './flamechart-view-container'
|
||||
import {SandwichViewState} from '../store/sandwich-view-state'
|
||||
import {FlamechartViewState} from '../store/flamechart-view-state'
|
||||
import {CanvasContext} from '../gl/canvas-context'
|
||||
import {Graphics} from '../gl/graphics'
|
||||
|
||||
const importModule = import('../import')
|
||||
@@ -169,7 +170,7 @@ export class Toolbar extends StatelessComponent<ToolbarProps> {
|
||||
}
|
||||
|
||||
interface GLCanvasProps {
|
||||
resizeCanvas: typeof Graphics.Context.prototype.resize
|
||||
canvasContext: CanvasContext | null
|
||||
setGLCanvas: (canvas: HTMLCanvasElement | null) => void
|
||||
}
|
||||
export class GLCanvas extends Component<GLCanvasProps, void> {
|
||||
@@ -185,37 +186,52 @@ export class GLCanvas extends Component<GLCanvasProps, void> {
|
||||
this.props.setGLCanvas(this.canvas)
|
||||
}
|
||||
|
||||
private maybeResize() {
|
||||
private maybeResize = () => {
|
||||
if (!this.canvas) return
|
||||
if (!this.props.canvasContext) return
|
||||
|
||||
let {width, height} = this.canvas.getBoundingClientRect()
|
||||
width = Math.floor(width) * window.devicePixelRatio
|
||||
height = Math.floor(height) * window.devicePixelRatio
|
||||
|
||||
// Still initializing: don't resize yet
|
||||
if (width < 4 || height < 4) return
|
||||
const oldWidth = this.canvas.width
|
||||
const oldHeight = this.canvas.height
|
||||
const widthInAppUnits = width
|
||||
const heightInAppUnits = height
|
||||
const widthInPixels = width * window.devicePixelRatio
|
||||
const heightInPixels = height * window.devicePixelRatio
|
||||
|
||||
// Already at the right size
|
||||
if (width === oldWidth && height === oldHeight) return
|
||||
|
||||
this.props.resizeCanvas(
|
||||
width,
|
||||
height,
|
||||
width / window.devicePixelRatio,
|
||||
height / window.devicePixelRatio,
|
||||
this.props.canvasContext.gl.resize(
|
||||
widthInPixels,
|
||||
heightInPixels,
|
||||
widthInAppUnits,
|
||||
heightInAppUnits,
|
||||
)
|
||||
this.props.canvasContext.gl.clear(new Graphics.Color(1, 1, 1, 1))
|
||||
}
|
||||
|
||||
onWindowResize = () => {
|
||||
this.maybeResize()
|
||||
if (this.props.canvasContext) {
|
||||
this.props.canvasContext.requestFrame()
|
||||
}
|
||||
window.addEventListener('resize', this.onWindowResize)
|
||||
}
|
||||
componentWillReceiveProps(nextProps: GLCanvasProps) {
|
||||
if (this.props.canvasContext !== nextProps.canvasContext) {
|
||||
if (this.props.canvasContext) {
|
||||
console.log('a')
|
||||
this.props.canvasContext.removeBeforeFrameHandler(this.maybeResize)
|
||||
}
|
||||
if (nextProps.canvasContext) {
|
||||
console.log('b')
|
||||
nextProps.canvasContext.addBeforeFrameHandler(this.maybeResize)
|
||||
nextProps.canvasContext.requestFrame()
|
||||
}
|
||||
}
|
||||
}
|
||||
componentDidMount() {
|
||||
window.addEventListener('resize', this.onWindowResize)
|
||||
requestAnimationFrame(() => this.maybeResize())
|
||||
}
|
||||
componentWillUnmount() {
|
||||
if (this.props.canvasContext) {
|
||||
this.props.canvasContext.removeBeforeFrameHandler(this.maybeResize)
|
||||
}
|
||||
window.removeEventListener('resize', this.onWindowResize)
|
||||
}
|
||||
render() {
|
||||
@@ -232,7 +248,6 @@ export interface ActiveProfileState {
|
||||
}
|
||||
|
||||
export type ApplicationProps = ApplicationState & {
|
||||
resizeCanvas: typeof Graphics.Context.prototype.resize
|
||||
setGLCanvas: (canvas: HTMLCanvasElement | null) => void
|
||||
setLoading: (loading: boolean) => void
|
||||
setError: (error: boolean) => void
|
||||
@@ -242,6 +257,7 @@ export type ApplicationProps = ApplicationState & {
|
||||
setFlattenRecursion: (flattenRecursion: boolean) => void
|
||||
setProfileIndexToView: (profileIndex: number) => void
|
||||
activeProfileState: ActiveProfileState | null
|
||||
canvasContext: CanvasContext | null
|
||||
}
|
||||
|
||||
export class Application extends StatelessComponent<ApplicationProps> {
|
||||
@@ -615,7 +631,7 @@ export class Application extends StatelessComponent<ApplicationProps> {
|
||||
onDragLeave={this.onDragLeave}
|
||||
className={css(style.root, this.props.dragActive && style.dragTargetRoot)}
|
||||
>
|
||||
<GLCanvas setGLCanvas={this.props.setGLCanvas} resizeCanvas={this.props.resizeCanvas} />
|
||||
<GLCanvas setGLCanvas={this.props.setGLCanvas} canvasContext={this.props.canvasContext} />
|
||||
<Toolbar
|
||||
saveFile={this.saveFile}
|
||||
browseForFile={this.browseForFile}
|
||||
|
||||
Reference in New Issue
Block a user