1
0
mirror of https://github.com/lxsang/Diya-API.git synced 2025-03-12 10:32:48 +01:00

Rendering context now use multiple texture units to boost performance (on RPI zero, the performance gain is more than 10 FPS )

This commit is contained in:
Dany LE 2022-08-14 15:42:59 +02:00
parent 677145f1a1
commit 142f14e936
10 changed files with 122 additions and 39 deletions

View File

@ -21,12 +21,14 @@ AssetManager class >> fromLocation: loc [
{ #category : #adding } { #category : #adding }
AssetManager >> addAsset: value [ AssetManager >> addAsset: value [
assets at: value name put: value assets at: value name put: value.
^ value
] ]
{ #category : #adding } { #category : #adding }
AssetManager >> addAssetName: name value: value [ AssetManager >> addAssetName: name value: value [
assets at: name put: value assets at: name put: value.
^ value
] ]
{ #category : #'instance creation' } { #category : #'instance creation' }

View File

@ -29,10 +29,9 @@ Diya2DPrimShape >> draw [
"configure vao vbo for texture QUAD" "configure vao vbo for texture QUAD"
self texture ifNotNil: [ self texture ifNotNil: [
self texture setup. self texture setup.
context texture0 setImage2D: self texture. context useTexture: self texture.
context texture0 active.
]. ].
context vbo data: GL_ARRAY_BUFFER data: vbuffer usage: GL_DYNAMIC_DRAW. context submitData: vbuffer.
OpenGL drawArrays: type first:0 count:((vbuffer size )>> 2 ). OpenGL drawArrays: type first:0 count:((vbuffer size )>> 2 ).
"reset value" "reset value"
self texture ifNotNil: [self texture drop.]. self texture ifNotNil: [self texture drop.].
@ -87,9 +86,16 @@ Diya2DPrimShape >> setUpShader [
super setUpShader. super setUpShader.
self shader self shader
setUniform: #u_color value: (self ? #color) asGL4FArray; setUniform: #u_color value: (self ? #color) asGL4FArray;
setUniform: #u_bg_color value: (self ? #bgColor) asGL4FArray; setUniform: #u_bg_color value: (self ? #bgColor) asGL4FArray.
setUniform: #u_texture_type value: self texture ifNotNil: [
(self texture ifNil: [ 0 ] ifNotNil:[self texture format]). self shader
setUniform: #u_texture value: self texture unit;
setUniform: #u_texture_type value: self texture format.
]
ifNil:
[
self shader setUniform: #u_texture_type value: 0.
].
] ]
{ #category : #accessing } { #category : #accessing }

View File

@ -13,7 +13,7 @@ DiyaExampleApp >> cleanup [
DiyaExampleApp >> defineStyleSheet [ DiyaExampleApp >> defineStyleSheet [
|fmgr style| |fmgr style|
fmgr := DiyaFontManager uniqueInstance. fmgr := DiyaFontManager uniqueInstance.
#(16 24) do:[:fontSize| #(16 18 24) do:[:fontSize|
self stdlog: 'Init font size ', fontSize asString, ' of ', fmgr defaultFamily. self stdlog: 'Init font size ', fontSize asString, ' of ', fmgr defaultFamily.
style := fmgr style: fmgr defaultStyle from: fmgr defaultFamily. style := fmgr style: fmgr defaultStyle from: fmgr defaultFamily.
style textureOf: fontSize. style textureOf: fontSize.
@ -85,11 +85,11 @@ DiyaExampleApp >> setup [
label styleName:#text_icon_1. label styleName:#text_icon_1.
label icon: 16rF254. label icon: 16rF254.
"node1 := root addNode: (DiyaRectangle size:100@150 shader: DiyaExampleShader uniqueInstance) at: 300 @ 40. node1 := root addNode: (DiyaRectangle size:100@150 shader: DiyaExampleShader uniqueInstance) at: 300 @ 40.
node1 rotation: 45. node1 rotation: 45.
node1 scale: 2.0@2.0. node1 scale: 2.0@2.0.
node1 on: #(mousebuttondown fingerdown) do:[:e| node1 on: #(mousebuttondown fingerdown) do:[:e|
label txt: 'RECT ', (node1 local: e mapped worldPosition) asIntegerPoint asString]." label txt: 'RECT ', (node1 local: e mapped worldPosition) asIntegerPoint asString].
img := root addNode: (DiyaImageView from:'mrsang.png') at: 10 @ 400. img := root addNode: (DiyaImageView from:'mrsang.png') at: 10 @ 400.
img styleName: #image_view. img styleName: #image_view.

View File

@ -66,7 +66,7 @@ DiyaFontManager >> loadFace: face [
DiyaFontManager >> loadFile: aFile [ DiyaFontManager >> loadFile: aFile [
| path face i numfaces | | path face i numfaces |
path := aFile fullName convertToWithConverter: UTF8TextConverter new. path := aFile fullName convertToWithConverter: UTF8TextConverter new.
Transcript show: 'Loading font file ', path;cr. self stdlog: 'Loading font file ', path.
i := 0. i := 0.
numfaces := nil. numfaces := nil.
[ face := FreeTypeFace basicNew [ face := FreeTypeFace basicNew

View File

@ -1,9 +1,6 @@
Class { Class {
#name : #DiyaImageTex, #name : #DiyaImageTex,
#superclass : #OpenGLTexImage2D, #superclass : #OpenGLTexImage2D,
#instVars : [
'name'
],
#pools : [ #pools : [
'OpenGLConstants', 'OpenGLConstants',
'OpenGLTypes' 'OpenGLTypes'
@ -55,6 +52,7 @@ DiyaImageTex >> fromDisplay: aRect as: assetName [
data ifNotNil: [data free]. data ifNotNil: [data free].
width := aRect extent x asInteger. width := aRect extent x asInteger.
height := aRect extent y asInteger. height := aRect extent y asInteger.
commited := false.
data := FFIExternalArray externalNewType: GLubyte size: self bytesSize. data := FFIExternalArray externalNewType: GLubyte size: self bytesSize.
LibC memset: data getHandle value: 0 size: data size. LibC memset: data getHandle value: 0 size: data size.
data autoRelease. data autoRelease.
@ -89,6 +87,7 @@ DiyaImageTex >> fromFile: aPath [
LibC memCopy: surface pixels getHandle to: data getHandle size: data size. LibC memCopy: surface pixels getHandle to: data getHandle size: data size.
SDL2 SDL2
freeSurface: surface. freeSurface: surface.
commited := false.
self stdlog: 'Loaded ', aPath fullName. self stdlog: 'Loaded ', aPath fullName.
] ]
@ -100,6 +99,7 @@ DiyaImageTex >> fromForm: aForm name: aName [
surface := self surfaceFromForm: aForm. surface := self surfaceFromForm: aForm.
width := surface w. width := surface w.
height := surface h. height := surface h.
commited := false.
data := FFIExternalArray externalNewType: GLubyte size: self bytesSize. data := FFIExternalArray externalNewType: GLubyte size: self bytesSize.
LibC memset: data getHandle value: 0 size: data size. LibC memset: data getHandle value: 0 size: data size.
data autoRelease. data autoRelease.
@ -124,11 +124,6 @@ DiyaImageTex >> mipmap [
^false ^false
] ]
{ #category : #accessing }
DiyaImageTex >> name [
^ name
]
{ #category : #accessing } { #category : #accessing }
DiyaImageTex >> setup [ DiyaImageTex >> setup [
OpenGLTexture OpenGLTexture

View File

@ -267,7 +267,6 @@ DiyaNode >> setUpShader [
setUniform: #u_time value: DiyaClock uniqueInstance elapsedTime asFloat; setUniform: #u_time value: DiyaClock uniqueInstance elapsedTime asFloat;
setUniform: #u_projection value: {GL_FALSE. context projection buffer}; setUniform: #u_projection value: {GL_FALSE. context projection buffer};
setUniform: #u_resolution value: { context resolution x. context resolution y }; setUniform: #u_resolution value: { context resolution x. context resolution y };
setUniform: #u_texture value: 0;
setUniform: #u_transform value: {GL_TRUE. mem}. setUniform: #u_transform value: {GL_TRUE. mem}.
context mouse ifNotNil: [ context mouse ifNotNil: [
"in shader, window origin is bottom left conor of the window "in shader, window origin is bottom left conor of the window

View File

@ -6,7 +6,7 @@ Class {
'display', 'display',
'vbo', 'vbo',
'vao', 'vao',
'texture0', 'textures',
'projection', 'projection',
'assets', 'assets',
'window', 'window',
@ -45,7 +45,8 @@ DiyaRendererContext >> destroy [
vao disableAttribute: 0. vao disableAttribute: 0.
vao delete. vao delete.
vbo delete. vbo delete.
texture0 delete. textures do: [:e | e key delete ].
textures := OrderedCollection new.
] ]
{ #category : #accessing } { #category : #accessing }
@ -58,18 +59,36 @@ DiyaRendererContext >> display: anObject [
display := anObject display := anObject
] ]
{ #category : #rendering }
DiyaRendererContext >> findTextureUnit [
textures withIndexDo: [ :e :i|
e value ifNil: [ ^ i - 1]
].
"random unit value"
^ (Random new nextInt: 32) - 1
]
{ #category : #accessing } { #category : #accessing }
DiyaRendererContext >> initialize [ DiyaRendererContext >> initialize [
super initialize. super initialize.
vbo := OpenGLVertexBuffer new. vbo := OpenGLVertexBuffer new.
vao := OpenGLVertexArray new. vao := OpenGLVertexArray new.
texture0 := OpenGLTexture fromUnit: 0. textures := Dictionary new.
vao bind. vao bind.
vbo bind: GL_ARRAY_BUFFER. vbo bind: GL_ARRAY_BUFFER.
projection := Array2D identity: 4. projection := Array2D identity: 4.
assets := AssetManager new. assets := AssetManager new.
vao enableAttribute: 0. vao enableAttribute: 0.
OpenGLVertexArray vertexAttributePointerIndex: 0 size:4 type: GL_FLOAT normalized: GL_FALSE stride: 16 pointer: nil. OpenGLVertexArray
vertexAttributePointerIndex: 0
size:4
type: GL_FLOAT
normalized: GL_FALSE
stride: 16
pointer: nil.
textures :=
(1 to: 32) collect:[:i|
(OpenGLTexture fromUnit: i - 1) -> nil] .
] ]
{ #category : #accessing } { #category : #accessing }
@ -109,9 +128,9 @@ DiyaRendererContext >> root [
] ]
{ #category : #accessing } { #category : #rendering }
DiyaRendererContext >> texture0 [ DiyaRendererContext >> submitData: vbuffer [
^ texture0 vbo data: GL_ARRAY_BUFFER data: vbuffer usage: GL_DYNAMIC_DRAW.
] ]
{ #category : #'transformation matrices' } { #category : #'transformation matrices' }
@ -119,6 +138,24 @@ DiyaRendererContext >> useProjection: aClass [
projection := aClass fromDisplay: self display projection := aClass fromDisplay: self display
] ]
{ #category : #rendering }
DiyaRendererContext >> useTexture: aTexture [
|assoc|
aTexture unit == -1 ifTrue:[ aTexture unit: self findTextureUnit].
assoc := textures at: aTexture unit + 1.
assoc value = aTexture ifFalse:[
"unregister current texture"
assoc value ifNotNil: [ assoc value commited: false ].
aTexture commited: false.
assoc value: aTexture.
].
assoc key active.
aTexture commited ifTrue:[ ^ self ].
"self stdlog: 'Commit data data to texture ', aTexture name, ' on Unit ', aTexture unit asString."
assoc key setImage2D: aTexture.
aTexture commited: true.
]
{ #category : #accessing } { #category : #accessing }
DiyaRendererContext >> vao [ DiyaRendererContext >> vao [
^ vao ^ vao

View File

@ -86,7 +86,7 @@ DiyaRootNode >> render [
node render. node render.
]. ].
(R isNotEmpty or: Q isNotEmpty) and: (R isNotEmpty or: Q isNotEmpty) and:
(DiyaClock uniqueInstance lapDelta asMilliSeconds < maxProcessingTime) (DiyaClock uniqueInstance lapDelta asMilliSeconds < maxProcessingTime)
] whileTrue ] whileTrue
] ]

View File

@ -26,7 +26,7 @@ OpenGLFontTex class >> fromFace: face ofSize: size [
^self new fromFace: face ofSize: size; yourself ^self new fromFace: face ofSize: size; yourself
] ]
{ #category : #'instance creation' } { #category : #processing }
OpenGLFontTex >> blitPixel8: bitmap at: offset size: size [ OpenGLFontTex >> blitPixel8: bitmap at: offset size: size [
size = (0@0) ifTrue:[^self]. size = (0@0) ifTrue:[^self].
0 to: size y - 1 do: [ :i| 0 to: size y - 1 do: [ :i|
@ -52,9 +52,9 @@ OpenGLFontTex >> charmap [
{ #category : #accessing } { #category : #accessing }
OpenGLFontTex >> drop [ OpenGLFontTex >> drop [
OpenGL OpenGL
pixelstorei: GL_UNPACK_ALIGNMENT param: 4; pixelstorei: GL_UNPACK_ALIGNMENT param: 4";
disable: GL_CULL_FACE; disable: GL_CULL_FACE;
disable: GL_BLEND. disable: GL_BLEND".
] ]
{ #category : #accessing } { #category : #accessing }
@ -67,6 +67,8 @@ OpenGLFontTex >> fromFace: aFace ofSize: size [
|minhang rec iptr charcode w numw| |minhang rec iptr charcode w numw|
fontSize := size. fontSize := size.
face := aFace. face := aFace.
commited := false.
name := aFace familyName, '@', aFace styleName,'@', size asString.
charmap := Dictionary new. charmap := Dictionary new.
face setPixelWidth:0 height: self fontSize. face setPixelWidth:0 height: self fontSize.
cellw := cellh := minhang := maxbearing := 0. cellw := cellh := minhang := maxbearing := 0.
@ -100,7 +102,7 @@ OpenGLFontTex >> fromFace: aFace ofSize: size [
iptr free. iptr free.
] ]
{ #category : #accessing } { #category : #processing }
OpenGLFontTex >> genGlyph:c [ OpenGLFontTex >> genGlyph:c [
|rec offset glyph gsize| |rec offset glyph gsize|
face setPixelWidth:0 height: self fontSize. face setPixelWidth:0 height: self fontSize.
@ -122,13 +124,20 @@ OpenGLFontTex >> genGlyph:c [
self reallocateBuffer. self reallocateBuffer.
]. ].
]. ].
commited := false.
^glyph ^glyph
] ]
{ #category : #processing }
OpenGLFontTex >> genPrintableASCII [
33 to: 126 do: [ :c| self genGlyph: c ]
]
{ #category : #accessing } { #category : #accessing }
OpenGLFontTex >> getGlyph: c [ OpenGLFontTex >> getGlyph: c [
^(self charmap at: c ifAbsentPut:[self genGlyph:c]) ^(self charmap at: c ifAbsentPut:[
self genGlyph:c])
] ]
{ #category : #initialization } { #category : #initialization }
@ -156,7 +165,7 @@ OpenGLFontTex >> meanww [
^ meanww ^ meanww
] ]
{ #category : #accessing } { #category : #processing }
OpenGLFontTex >> reallocateBuffer [ OpenGLFontTex >> reallocateBuffer [
|newbuffer| |newbuffer|
maxrows := maxrows + 4. maxrows := maxrows + 4.
@ -169,12 +178,12 @@ OpenGLFontTex >> reallocateBuffer [
] ]
{ #category : #accessing } { #category : #initialization }
OpenGLFontTex >> setup [ OpenGLFontTex >> setup [
OpenGL OpenGL
enable: GL_CULL_FACE; "enable: GL_CULL_FACE;
enable: GL_BLEND; enable: GL_BLEND;
blendFnWithSfactor: GL_SRC_ALPHA dfactor: GL_ONE_MINUS_SRC_ALPHA; blendFnWithSfactor: GL_SRC_ALPHA dfactor: GL_ONE_MINUS_SRC_ALPHA;"
pixelstorei: GL_UNPACK_ALIGNMENT param: 1. pixelstorei: GL_UNPACK_ALIGNMENT param: 1.
OpenGLTexture OpenGLTexture
parameteri: GL_TEXTURE_2D pname: GL_TEXTURE_WRAP_S param: GL_CLAMP_TO_EDGE; parameteri: GL_TEXTURE_2D pname: GL_TEXTURE_WRAP_S param: GL_CLAMP_TO_EDGE;

View File

@ -10,7 +10,10 @@ Class {
'border', 'border',
'format', 'format',
'type', 'type',
'data' 'data',
'unit',
'commited',
'name'
], ],
#pools : [ #pools : [
'OpenGLConstants', 'OpenGLConstants',
@ -34,6 +37,16 @@ OpenGLTexImage2D >> bytesSize [
^(width * height) << 2 ^(width * height) << 2
] ]
{ #category : #accessing }
OpenGLTexImage2D >> commited [
^ commited
]
{ #category : #accessing }
OpenGLTexImage2D >> commited: anObject [
commited := anObject
]
{ #category : #accessing } { #category : #accessing }
OpenGLTexImage2D >> data [ OpenGLTexImage2D >> data [
^ data ^ data
@ -87,6 +100,13 @@ OpenGLTexImage2D >> height: anObject [
height := anObject height := anObject
] ]
{ #category : #initialization }
OpenGLTexImage2D >> initialize [
super initialize.
unit := -1.
commited := false
]
{ #category : #accessing } { #category : #accessing }
OpenGLTexImage2D >> internalFormat [ OpenGLTexImage2D >> internalFormat [
^ internalFormat ^ internalFormat
@ -112,6 +132,11 @@ OpenGLTexImage2D >> mipmap [
^false ^false
] ]
{ #category : #accessing }
OpenGLTexImage2D >> name [
^ name
]
{ #category : #accessing } { #category : #accessing }
OpenGLTexImage2D >> setup [ OpenGLTexImage2D >> setup [
^self subclassResponsibility ^self subclassResponsibility
@ -137,6 +162,16 @@ OpenGLTexImage2D >> type: anObject [
type := anObject type := anObject
] ]
{ #category : #accessing }
OpenGLTexImage2D >> unit [
^ unit
]
{ #category : #accessing }
OpenGLTexImage2D >> unit: anObject [
unit := anObject
]
{ #category : #accessing } { #category : #accessing }
OpenGLTexImage2D >> width [ OpenGLTexImage2D >> width [
^ width ^ width