Skip to content
Snippets Groups Projects
Commit 5ab1de67 authored by Alexander Rose's avatar Alexander Rose
Browse files

fixes for readPixelsAsync

parent 22a42682
Branches
Tags
No related merge requests found
......@@ -244,7 +244,7 @@ namespace Canvas3D {
}
async function identify(x: number, y: number): Promise<PickingId | undefined> {
if (pickDirty) return undefined
if (pickDirty || isPicking) return undefined
isPicking = true
......@@ -259,23 +259,21 @@ namespace Canvas3D {
objectPickTarget.bind()
await webgl.readPixelsAsync(xp, yp, 1, 1, buffer)
const objectId = decodeIdRGB(buffer[0], buffer[1], buffer[2])
if (objectId === -1) return
instancePickTarget.bind()
await webgl.readPixels(xp, yp, 1, 1, buffer)
await webgl.readPixelsAsync(xp, yp, 1, 1, buffer)
const instanceId = decodeIdRGB(buffer[0], buffer[1], buffer[2])
if (instanceId === -1) return
groupPickTarget.bind()
await webgl.readPixels(xp, yp, 1, 1, buffer)
await webgl.readPixelsAsync(xp, yp, 1, 1, buffer)
const groupId = decodeIdRGB(buffer[0], buffer[1], buffer[2])
if (groupId === -1) return
isPicking = false
// TODO
if (objectId === -1 || instanceId === -1 || groupId === -1) {
return { objectId: -1, instanceId: -1, groupId: -1 }
} else {
return { objectId, instanceId, groupId }
}
return { objectId, instanceId, groupId }
}
function add(repr: Representation.Any) {
......
......@@ -55,39 +55,42 @@ function unbindFramebuffer(gl: GLRenderingContext) {
const tmpPixel = new Uint8Array(1 * 4);
function fence(gl: WebGL2RenderingContext) {
function checkSync(gl: WebGL2RenderingContext, sync: WebGLSync, resolve: () => void) {
if (gl.getSyncParameter(sync, gl.SYNC_STATUS) === gl.SIGNALED) {
gl.deleteSync(sync)
resolve()
} else {
Scheduler.setImmediate(checkSync, gl, sync, resolve)
}
}
function fence(gl: WebGL2RenderingContext, resolve: () => void) {
const sync = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0)
if (!sync) {
console.warn('Could not create a WebGLSync object')
gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, tmpPixel)
resolve()
} else {
Scheduler.setImmediate(checkSync, gl, sync, resolve)
}
}
let SentWebglSyncObjectNotSupportedInWebglMessage = false
function waitForGpuCommandsComplete(gl: GLRenderingContext): Promise<void> {
return new Promise(resolve => {
gl.finish()
const sync = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0)
if (!sync) {
console.warn('could not create a WebGL2 sync object')
gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, tmpPixel)
resolve()
if (isWebGL2(gl)) {
fence(gl, resolve)
} else {
gl.flush(); // Ensure the fence is submitted.
const check = () => {
const status = gl.getSyncParameter(sync, gl.SYNC_STATUS)
if (status === gl.SIGNALED) {
gl.deleteSync(sync)
resolve()
} else {
Scheduler.setImmediate(check, 0)
}
if (!SentWebglSyncObjectNotSupportedInWebglMessage) {
console.info('Sync object not supported in WebGL')
SentWebglSyncObjectNotSupportedInWebglMessage = true
}
Scheduler.setImmediate(check, 0)
gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, tmpPixel)
resolve()
}
})
}
async function waitForGpuCommandsComplete(gl: GLRenderingContext) {
if (isWebGL2(gl)) {
await fence(gl)
} else {
console.info('webgl sync object not supported in webgl 1')
gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, tmpPixel)
}
}
export function createImageData(buffer: ArrayLike<number>, width: number, height: number) {
const w = width * 4
const h = height
......@@ -198,17 +201,34 @@ export function createContext(gl: GLRenderingContext): WebGLContext {
let readPixelsAsync: (x: number, y: number, width: number, height: number, buffer: Uint8Array) => Promise<void>
if (isWebGL2(gl)) {
const pbo = gl.createBuffer()
readPixelsAsync = async (x: number, y: number, width: number, height: number, buffer: Uint8Array) => {
let _buffer: Uint8Array | undefined = void 0
let _resolve: (() => void) | undefined = void 0
let _reading = false
const bindPBO = () => {
gl.bindBuffer(gl.PIXEL_PACK_BUFFER, pbo)
gl.getBufferSubData(gl.PIXEL_PACK_BUFFER, 0, _buffer!)
gl.bindBuffer(gl.PIXEL_PACK_BUFFER, null)
_reading = false
_resolve!()
_resolve = void 0
_buffer = void 0
}
readPixelsAsync = (x: number, y: number, width: number, height: number, buffer: Uint8Array): Promise<void> => new Promise<void>((resolve, reject) => {
if (_reading) {
reject('Can not call multiple readPixelsAsync at the same time')
return
}
_reading = true;
gl.bindBuffer(gl.PIXEL_PACK_BUFFER, pbo)
gl.bufferData(gl.PIXEL_PACK_BUFFER, width * height * 4, gl.STREAM_READ)
gl.readPixels(x, y, width, height, gl.RGBA, gl.UNSIGNED_BYTE, 0)
gl.bindBuffer(gl.PIXEL_PACK_BUFFER, null)
// need to unbind/bind PBO before/after async awaiting the fence
await fence(gl)
gl.bindBuffer(gl.PIXEL_PACK_BUFFER, pbo)
gl.getBufferSubData(gl.PIXEL_PACK_BUFFER, 0, buffer)
gl.bindBuffer(gl.PIXEL_PACK_BUFFER, null)
}
_resolve = resolve
_buffer = buffer
fence(gl, bindPBO)
})
} else {
readPixelsAsync = async (x: number, y: number, width: number, height: number, buffer: Uint8Array) => {
gl.readPixels(x, y, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buffer)
......
......@@ -38,7 +38,7 @@ export async function GaussianDensityCPU(ctx: RuntimeContext, position: Position
const delta = getDelta(Box3D.expand(Box3D.empty(), box, Vec3.create(pad, pad, pad)), resolution)
const dim = Vec3.zero()
Vec3.ceil(dim, Vec3.mul(dim, extent, delta))
console.log('grid dim', dim)
// console.log('grid dim', dim)
const space = Tensor.Space(dim, [0, 1, 2], Float32Array)
const data = space.create()
......@@ -63,7 +63,7 @@ export async function GaussianDensityCPU(ctx: RuntimeContext, position: Position
const gridPad = 1 / Math.max(...delta)
console.time('gaussian density cpu')
// console.time('gaussian density cpu')
for (let i = 0; i < n; ++i) {
const j = OrderedSet.getAt(indices, i)
......@@ -105,7 +105,7 @@ export async function GaussianDensityCPU(ctx: RuntimeContext, position: Position
await ctx.update({ message: 'filling density grid', current: i, max: n })
}
}
console.timeEnd('gaussian density cpu')
// console.timeEnd('gaussian density cpu')
const transform = Mat4.identity()
Mat4.fromScaling(transform, Vec3.inverse(Vec3.zero(), delta))
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment