Skip to content

Commit

Permalink
Don't upload texture if locked using TEXTURELOCK_READ (#6003)
Browse files Browse the repository at this point in the history
* Don't upload texture if locked using TEXTURELOCK_READ

* Don't expose _lockedLevel yet

* Better assertions, upgrade double-unlock from log to warning
  • Loading branch information
liamdon committed Feb 2, 2024
1 parent 204b64c commit 912a837
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 5 deletions.
7 changes: 7 additions & 0 deletions src/platform/graphics/constants.js
Expand Up @@ -1324,6 +1324,13 @@ export const STENCILOP_DECREMENTWRAP = 6;
*/
export const STENCILOP_INVERT = 7;

/**
* The texture is not in a locked state.
*
* @type {number}
*/
export const TEXTURELOCK_NONE = 0;

/**
* Read only. Any changes to the locked mip level's pixels will not update the texture.
*
Expand Down
43 changes: 38 additions & 5 deletions src/platform/graphics/texture.js
Expand Up @@ -16,7 +16,7 @@ import {
TEXTURELOCK_WRITE,
TEXTUREPROJECTION_NONE, TEXTUREPROJECTION_CUBE,
TEXTURETYPE_DEFAULT, TEXTURETYPE_RGBM, TEXTURETYPE_RGBE, TEXTURETYPE_RGBP, TEXTURETYPE_SWIZZLEGGGR,
isIntegerPixelFormat, FILTER_NEAREST
isIntegerPixelFormat, FILTER_NEAREST, TEXTURELOCK_NONE, TEXTURELOCK_READ
} from './constants.js';

let id = 0;
Expand Down Expand Up @@ -47,6 +47,9 @@ class Texture {
/** @protected */
_lockedLevel = -1;

/** @protected */
_lockedMode = TEXTURELOCK_NONE;

/**
* A render version used to track the last time the texture properties requiring bind group
* to be updated were changed.
Expand Down Expand Up @@ -377,6 +380,20 @@ class Texture {
return this.mipmaps ? TextureUtils.calcMipLevelsCount(this.width, this.height) : 1;
}

/**
* Returns the current lock mode. One of:
*
* - {@link TEXTURELOCK_NONE}
* - {@link TEXTURELOCK_READ}
* - {@link TEXTURELOCK_WRITE}
*
* @ignore
* @type {number}
*/
get lockedMode() {
return this._lockedMode;
}

/**
* The minification filter to be applied to the texture. Can be:
*
Expand Down Expand Up @@ -773,6 +790,19 @@ class Texture {
options.face ??= 0;
options.mode ??= TEXTURELOCK_WRITE;

Debug.assert(
this._lockedMode === TEXTURELOCK_NONE,
'The texture is already locked. Call `texture.unlock()` before attempting to lock again.',
this
);

Debug.assert(
options.mode === TEXTURELOCK_READ || options.mode === TEXTURELOCK_WRITE,
'Cannot lock a texture with TEXTURELOCK_NONE. To unlock a texture, call `texture.unlock()`.',
this
);

this._lockedMode = options.mode;
this._lockedLevel = options.level;

const levels = this.cubemap ? this._levels[options.face] : this._levels;
Expand Down Expand Up @@ -900,13 +930,16 @@ class Texture {
* Unlocks the currently locked mip level and uploads it to VRAM.
*/
unlock() {
if (this._lockedLevel === -1) {
Debug.log("pc.Texture#unlock: Attempting to unlock a texture that is not locked.", this);
if (this._lockedMode === TEXTURELOCK_NONE) {
Debug.warn("pc.Texture#unlock: Attempting to unlock a texture that is not locked.", this);
}

// Upload the new pixel data
this.upload();
// Upload the new pixel data if locked in write mode (default)
if (this._lockedMode === TEXTURELOCK_WRITE) {
this.upload();
}
this._lockedLevel = -1;
this._lockedMode = TEXTURELOCK_NONE;
}

/**
Expand Down

0 comments on commit 912a837

Please sign in to comment.