Skip to content

Commit 6591d25

Browse files
authored
Renderers: Cache pixel storage parameters. (#33227)
1 parent c6167f9 commit 6591d25

8 files changed

Lines changed: 153 additions & 65 deletions

File tree

examples/webgl_materials_texture_partialupdate.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363

6464
const data = new Uint8Array( width * height * 4 );
6565
dataTexture = new THREE.DataTexture( data, width, height );
66+
dataTexture.colorSpace = THREE.SRGBColorSpace;
6667

6768
//
6869

examples/webgpu_textures_partialupdate.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272

7373
const data = new Uint8Array( width * height * 4 );
7474
dataTexture = new THREE.DataTexture( data, width, height );
75+
dataTexture.colorSpace = THREE.SRGBColorSpace;
7576

7677
//
7778

examples/webxr_vr_layers.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,7 @@
401401

402402
const glayer = xr.getBinding().getSubImage( quadLayerPlain, frame );
403403
renderer.state.bindTexture( gl.TEXTURE_2D, glayer.colorTexture );
404-
gl.pixelStorei( gl.UNPACK_FLIP_Y_WEBGL, true );
404+
renderer.state.pixelStorei( gl.UNPACK_FLIP_Y_WEBGL, true );
405405
gl.texSubImage2D( gl.TEXTURE_2D, 0,
406406
( snellenConfig.textureSizePx - snellenConfig.widthPx ) / 2,
407407
( snellenConfig.textureSizePx - snellenConfig.heightPx ) / 2,
@@ -415,7 +415,7 @@
415415

416416
const glayer = xr.getBinding().getSubImage( quadLayerMips, frame );
417417
renderer.state.bindTexture( gl.TEXTURE_2D, glayer.colorTexture );
418-
gl.pixelStorei( gl.UNPACK_FLIP_Y_WEBGL, true );
418+
renderer.state.pixelStorei( gl.UNPACK_FLIP_Y_WEBGL, true );
419419
gl.texSubImage2D( gl.TEXTURE_2D, 0,
420420
( snellenConfig.textureSizePx - snellenConfig.widthPx ) / 2,
421421
( snellenConfig.textureSizePx - snellenConfig.heightPx ) / 2,
@@ -430,7 +430,7 @@
430430

431431
const glayer = xr.getBinding().getSubImage( guiLayer, frame );
432432
renderer.state.bindTexture( gl.TEXTURE_2D, glayer.colorTexture );
433-
gl.pixelStorei( gl.UNPACK_FLIP_Y_WEBGL, true );
433+
renderer.state.pixelStorei( gl.UNPACK_FLIP_Y_WEBGL, true );
434434
const canvas = guiMesh.material.map.image;
435435
gl.texSubImage2D( gl.TEXTURE_2D, 0, 0, 0, canvas.width, canvas.height, gl.RGBA, gl.UNSIGNED_BYTE, canvas );
436436
guiLayer.needsUpdate = false;

src/renderers/WebGLRenderer.js

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3289,22 +3289,22 @@ class WebGLRenderer {
32893289

32903290
state.activeTexture( _gl.TEXTURE0 ); // see #33153
32913291

3292-
_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, dstTexture.flipY );
3293-
_gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, dstTexture.premultiplyAlpha );
3294-
_gl.pixelStorei( _gl.UNPACK_ALIGNMENT, dstTexture.unpackAlignment );
3292+
state.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, dstTexture.flipY );
3293+
state.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, dstTexture.premultiplyAlpha );
3294+
state.pixelStorei( _gl.UNPACK_ALIGNMENT, dstTexture.unpackAlignment );
32953295

32963296
// used for copying data from cpu
3297-
const currentUnpackRowLen = _gl.getParameter( _gl.UNPACK_ROW_LENGTH );
3298-
const currentUnpackImageHeight = _gl.getParameter( _gl.UNPACK_IMAGE_HEIGHT );
3299-
const currentUnpackSkipPixels = _gl.getParameter( _gl.UNPACK_SKIP_PIXELS );
3300-
const currentUnpackSkipRows = _gl.getParameter( _gl.UNPACK_SKIP_ROWS );
3301-
const currentUnpackSkipImages = _gl.getParameter( _gl.UNPACK_SKIP_IMAGES );
3302-
3303-
_gl.pixelStorei( _gl.UNPACK_ROW_LENGTH, image.width );
3304-
_gl.pixelStorei( _gl.UNPACK_IMAGE_HEIGHT, image.height );
3305-
_gl.pixelStorei( _gl.UNPACK_SKIP_PIXELS, minX );
3306-
_gl.pixelStorei( _gl.UNPACK_SKIP_ROWS, minY );
3307-
_gl.pixelStorei( _gl.UNPACK_SKIP_IMAGES, minZ );
3297+
const currentUnpackRowLen = state.getParameter( _gl.UNPACK_ROW_LENGTH );
3298+
const currentUnpackImageHeight = state.getParameter( _gl.UNPACK_IMAGE_HEIGHT );
3299+
const currentUnpackSkipPixels = state.getParameter( _gl.UNPACK_SKIP_PIXELS );
3300+
const currentUnpackSkipRows = state.getParameter( _gl.UNPACK_SKIP_ROWS );
3301+
const currentUnpackSkipImages = state.getParameter( _gl.UNPACK_SKIP_IMAGES );
3302+
3303+
state.pixelStorei( _gl.UNPACK_ROW_LENGTH, image.width );
3304+
state.pixelStorei( _gl.UNPACK_IMAGE_HEIGHT, image.height );
3305+
state.pixelStorei( _gl.UNPACK_SKIP_PIXELS, minX );
3306+
state.pixelStorei( _gl.UNPACK_SKIP_ROWS, minY );
3307+
state.pixelStorei( _gl.UNPACK_SKIP_IMAGES, minZ );
33083308

33093309
// set up the src texture
33103310
const isSrc3D = srcTexture.isDataArrayTexture || srcTexture.isData3DTexture;
@@ -3430,11 +3430,11 @@ class WebGLRenderer {
34303430
}
34313431

34323432
// reset values
3433-
_gl.pixelStorei( _gl.UNPACK_ROW_LENGTH, currentUnpackRowLen );
3434-
_gl.pixelStorei( _gl.UNPACK_IMAGE_HEIGHT, currentUnpackImageHeight );
3435-
_gl.pixelStorei( _gl.UNPACK_SKIP_PIXELS, currentUnpackSkipPixels );
3436-
_gl.pixelStorei( _gl.UNPACK_SKIP_ROWS, currentUnpackSkipRows );
3437-
_gl.pixelStorei( _gl.UNPACK_SKIP_IMAGES, currentUnpackSkipImages );
3433+
state.pixelStorei( _gl.UNPACK_ROW_LENGTH, currentUnpackRowLen );
3434+
state.pixelStorei( _gl.UNPACK_IMAGE_HEIGHT, currentUnpackImageHeight );
3435+
state.pixelStorei( _gl.UNPACK_SKIP_PIXELS, currentUnpackSkipPixels );
3436+
state.pixelStorei( _gl.UNPACK_SKIP_ROWS, currentUnpackSkipRows );
3437+
state.pixelStorei( _gl.UNPACK_SKIP_IMAGES, currentUnpackSkipImages );
34383438

34393439
// Generate mipmaps only when copying level 0
34403440
if ( dstLevel === 0 && dstTexture.generateMipmaps ) {

src/renderers/webgl-fallback/utils/WebGLState.js

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ class WebGLState {
5050
// documented for convenience reasons.
5151

5252
this.enabled = {};
53+
this.parameters = {};
5354
this.currentFlipSided = null;
5455
this.currentCullFace = null;
5556
this.currentProgram = null;
@@ -1291,7 +1292,6 @@ class WebGLState {
12911292

12921293
}
12931294

1294-
12951295
/**
12961296
* Unbinds the current bound texture.
12971297
*
@@ -1315,6 +1315,47 @@ class WebGLState {
13151315

13161316
}
13171317

1318+
/**
1319+
* Returns the value for the given parameter.
1320+
*
1321+
* @param {number} name - The paramter to get the value for.
1322+
* @return {any} The value for the given parameter.
1323+
*/
1324+
getParameter( name ) {
1325+
1326+
const { gl, parameters } = this;
1327+
1328+
if ( parameters[ name ] !== undefined ) {
1329+
1330+
return parameters[ name ];
1331+
1332+
} else {
1333+
1334+
return gl.getParameter( name );
1335+
1336+
}
1337+
1338+
}
1339+
1340+
/**
1341+
* Specifies a pixel storage mode.
1342+
*
1343+
* @param {number} name - The parameter to set.
1344+
* @param {any} value - A value to set the parameter to.
1345+
*/
1346+
pixelStorei( name, value ) {
1347+
1348+
const { gl, parameters } = this;
1349+
1350+
if ( parameters[ name ] !== value ) {
1351+
1352+
gl.pixelStorei( name, value );
1353+
parameters[ name ] = value;
1354+
1355+
}
1356+
1357+
}
1358+
13181359
}
13191360

13201361
export default WebGLState;

src/renderers/webgl-fallback/utils/WebGLTextureUtils.js

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -320,15 +320,16 @@ class WebGLTextureUtils {
320320
setTextureParameters( textureType, texture ) {
321321

322322
const { gl, extensions, backend } = this;
323+
const { state } = this.backend;
323324

324325
const workingPrimaries = ColorManagement.getPrimaries( ColorManagement.workingColorSpace );
325326
const texturePrimaries = texture.colorSpace === NoColorSpace ? null : ColorManagement.getPrimaries( texture.colorSpace );
326327
const unpackConversion = texture.colorSpace === NoColorSpace || workingPrimaries === texturePrimaries ? gl.NONE : gl.BROWSER_DEFAULT_WEBGL;
327328

328-
gl.pixelStorei( gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );
329-
gl.pixelStorei( gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha );
330-
gl.pixelStorei( gl.UNPACK_ALIGNMENT, texture.unpackAlignment );
331-
gl.pixelStorei( gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, unpackConversion );
329+
state.pixelStorei( gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );
330+
state.pixelStorei( gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha );
331+
state.pixelStorei( gl.UNPACK_ALIGNMENT, texture.unpackAlignment );
332+
state.pixelStorei( gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, unpackConversion );
332333

333334
gl.texParameteri( textureType, gl.TEXTURE_WRAP_S, wrappingToGL[ texture.wrapS ] );
334335
gl.texParameteri( textureType, gl.TEXTURE_WRAP_T, wrappingToGL[ texture.wrapT ] );
@@ -470,6 +471,7 @@ class WebGLTextureUtils {
470471
copyBufferToTexture( buffer, texture ) {
471472

472473
const { gl, backend } = this;
474+
const { state } = backend;
473475

474476
const { textureGPU, glTextureType, glFormat, glType } = backend.get( texture );
475477

@@ -479,8 +481,8 @@ class WebGLTextureUtils {
479481

480482
backend.state.bindTexture( glTextureType, textureGPU );
481483

482-
gl.pixelStorei( gl.UNPACK_FLIP_Y_WEBGL, false );
483-
gl.pixelStorei( gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false );
484+
state.pixelStorei( gl.UNPACK_FLIP_Y_WEBGL, false );
485+
state.pixelStorei( gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false );
484486
gl.texSubImage2D( glTextureType, 0, 0, 0, width, height, glFormat, glType, 0 );
485487

486488
gl.bindBuffer( gl.PIXEL_UNPACK_BUFFER, null );
@@ -832,22 +834,22 @@ class WebGLTextureUtils {
832834

833835
}
834836

835-
gl.pixelStorei( gl.UNPACK_FLIP_Y_WEBGL, dstTexture.flipY );
836-
gl.pixelStorei( gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, dstTexture.premultiplyAlpha );
837-
gl.pixelStorei( gl.UNPACK_ALIGNMENT, dstTexture.unpackAlignment );
837+
state.pixelStorei( gl.UNPACK_FLIP_Y_WEBGL, dstTexture.flipY );
838+
state.pixelStorei( gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, dstTexture.premultiplyAlpha );
839+
state.pixelStorei( gl.UNPACK_ALIGNMENT, dstTexture.unpackAlignment );
838840

839841
// used for copying data from cpu
840-
const currentUnpackRowLen = gl.getParameter( gl.UNPACK_ROW_LENGTH );
841-
const currentUnpackImageHeight = gl.getParameter( gl.UNPACK_IMAGE_HEIGHT );
842-
const currentUnpackSkipPixels = gl.getParameter( gl.UNPACK_SKIP_PIXELS );
843-
const currentUnpackSkipRows = gl.getParameter( gl.UNPACK_SKIP_ROWS );
844-
const currentUnpackSkipImages = gl.getParameter( gl.UNPACK_SKIP_IMAGES );
845-
846-
gl.pixelStorei( gl.UNPACK_ROW_LENGTH, image.width );
847-
gl.pixelStorei( gl.UNPACK_IMAGE_HEIGHT, image.height );
848-
gl.pixelStorei( gl.UNPACK_SKIP_PIXELS, minX );
849-
gl.pixelStorei( gl.UNPACK_SKIP_ROWS, minY );
850-
gl.pixelStorei( gl.UNPACK_SKIP_IMAGES, minZ );
842+
const currentUnpackRowLen = state.getParameter( gl.UNPACK_ROW_LENGTH );
843+
const currentUnpackImageHeight = state.getParameter( gl.UNPACK_IMAGE_HEIGHT );
844+
const currentUnpackSkipPixels = state.getParameter( gl.UNPACK_SKIP_PIXELS );
845+
const currentUnpackSkipRows = state.getParameter( gl.UNPACK_SKIP_ROWS );
846+
const currentUnpackSkipImages = state.getParameter( gl.UNPACK_SKIP_IMAGES );
847+
848+
state.pixelStorei( gl.UNPACK_ROW_LENGTH, image.width );
849+
state.pixelStorei( gl.UNPACK_IMAGE_HEIGHT, image.height );
850+
state.pixelStorei( gl.UNPACK_SKIP_PIXELS, minX );
851+
state.pixelStorei( gl.UNPACK_SKIP_ROWS, minY );
852+
state.pixelStorei( gl.UNPACK_SKIP_IMAGES, minZ );
851853

852854
// set up the src texture
853855
const isSrc3D = srcTexture.isDataArrayTexture || srcTexture.isData3DTexture || dstTexture.isArrayTexture;
@@ -981,11 +983,11 @@ class WebGLTextureUtils {
981983
}
982984

983985
// reset values
984-
gl.pixelStorei( gl.UNPACK_ROW_LENGTH, currentUnpackRowLen );
985-
gl.pixelStorei( gl.UNPACK_IMAGE_HEIGHT, currentUnpackImageHeight );
986-
gl.pixelStorei( gl.UNPACK_SKIP_PIXELS, currentUnpackSkipPixels );
987-
gl.pixelStorei( gl.UNPACK_SKIP_ROWS, currentUnpackSkipRows );
988-
gl.pixelStorei( gl.UNPACK_SKIP_IMAGES, currentUnpackSkipImages );
986+
state.pixelStorei( gl.UNPACK_ROW_LENGTH, currentUnpackRowLen );
987+
state.pixelStorei( gl.UNPACK_IMAGE_HEIGHT, currentUnpackImageHeight );
988+
state.pixelStorei( gl.UNPACK_SKIP_PIXELS, currentUnpackSkipPixels );
989+
state.pixelStorei( gl.UNPACK_SKIP_ROWS, currentUnpackSkipRows );
990+
state.pixelStorei( gl.UNPACK_SKIP_IMAGES, currentUnpackSkipImages );
989991

990992
// Generate mipmaps only when copying level 0
991993
if ( dstLevel === 0 && dstTexture.generateMipmaps ) {

src/renderers/webgl/WebGLState.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,7 @@ function WebGLState( gl, extensions ) {
353353
const uboProgramMap = new WeakMap();
354354

355355
let enabledCapabilities = {};
356+
let parameters = {};
356357

357358
let currentBoundFramebuffers = {};
358359
let currentDrawbuffers = new WeakMap();
@@ -1112,6 +1113,31 @@ function WebGLState( gl, extensions ) {
11121113

11131114
}
11141115

1116+
function getParameter( name ) {
1117+
1118+
if ( parameters[ name ] !== undefined ) {
1119+
1120+
return parameters[ name ];
1121+
1122+
} else {
1123+
1124+
return gl.getParameter( name );
1125+
1126+
}
1127+
1128+
}
1129+
1130+
function pixelStorei( name, value ) {
1131+
1132+
if ( parameters[ name ] !== value ) {
1133+
1134+
gl.pixelStorei( name, value );
1135+
parameters[ name ] = value;
1136+
1137+
}
1138+
1139+
}
1140+
11151141
//
11161142

11171143
function scissor( scissor ) {
@@ -1228,9 +1254,24 @@ function WebGLState( gl, extensions ) {
12281254
gl.scissor( 0, 0, gl.canvas.width, gl.canvas.height );
12291255
gl.viewport( 0, 0, gl.canvas.width, gl.canvas.height );
12301256

1257+
gl.pixelStorei( gl.PACK_ALIGNMENT, 4 );
1258+
gl.pixelStorei( gl.UNPACK_ALIGNMENT, 4 );
1259+
gl.pixelStorei( gl.UNPACK_FLIP_Y_WEBGL, false );
1260+
gl.pixelStorei( gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false );
1261+
gl.pixelStorei( gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, gl.BROWSER_DEFAULT_WEBGL );
1262+
gl.pixelStorei( gl.PACK_ROW_LENGTH, 0 );
1263+
gl.pixelStorei( gl.PACK_SKIP_PIXELS, 0 );
1264+
gl.pixelStorei( gl.PACK_SKIP_ROWS, 0 );
1265+
gl.pixelStorei( gl.UNPACK_ROW_LENGTH, 0 );
1266+
gl.pixelStorei( gl.UNPACK_IMAGE_HEIGHT, 0 );
1267+
gl.pixelStorei( gl.UNPACK_SKIP_PIXELS, 0 );
1268+
gl.pixelStorei( gl.UNPACK_SKIP_ROWS, 0 );
1269+
gl.pixelStorei( gl.UNPACK_SKIP_IMAGES, 0 );
1270+
12311271
// reset internals
12321272

12331273
enabledCapabilities = {};
1274+
parameters = {};
12341275

12351276
currentTextureSlot = null;
12361277
currentBoundTextures = {};
@@ -1304,6 +1345,8 @@ function WebGLState( gl, extensions ) {
13041345
compressedTexImage3D: compressedTexImage3D,
13051346
texImage2D: texImage2D,
13061347
texImage3D: texImage3D,
1348+
pixelStorei: pixelStorei,
1349+
getParameter: getParameter,
13071350

13081351
updateUBOMapping: updateUBOMapping,
13091352
uniformBlockBinding: uniformBlockBinding,

0 commit comments

Comments
 (0)