Clean up Core Text rendering code, and factor our basis/cache and basis/opengl/texture-cache

db4
Slava Pestov 2009-02-10 02:45:43 -06:00
parent 6235e95052
commit 5be7a6777b
12 changed files with 142 additions and 92 deletions

1
basis/cache/authors.txt vendored Normal file
View File

@ -0,0 +1 @@
Slava Pestov

4
basis/cache/cache-tests.factor vendored Normal file
View File

@ -0,0 +1,4 @@
! Copyright (C) 2009 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: tools.test cache ;
IN: cache.tests

36
basis/cache/cache.factor vendored Normal file
View File

@ -0,0 +1,36 @@
! Copyright (C) 2009 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: kernel assocs math accessors destructors fry ;
IN: cache
SLOT: age
GENERIC: age ( obj -- )
M: object age [ 1+ ] change-age drop ;
TUPLE: cache-assoc assoc max-age disposed ;
: <cache-assoc> ( -- cache )
H{ } clone 10 f cache-assoc boa ;
M: cache-assoc assoc-size assoc>> assoc-size ;
M: cache-assoc at* assoc>> at* [ dup [ 0 >>age ] when ] dip ;
M: cache-assoc set-at dup check-disposed assoc>> set-at ;
M: cache-assoc clear-assoc assoc>> clear-assoc ;
M: cache-assoc >alist assoc>> >alist ;
INSTANCE: cache-assoc assoc
: purge-cache ( cache -- )
dup max-age>> '[
[ nip dup age age>> _ >= ] assoc-partition
[ values dispose-each ] dip
] change-assoc drop ;
M: cache-assoc dispose*
assoc>> [ values dispose-each ] [ clear-assoc ] bi ;

View File

@ -3,7 +3,7 @@
USING: arrays alien alien.c-types alien.syntax kernel USING: arrays alien alien.c-types alien.syntax kernel
destructors accessors fry words hashtables strings destructors accessors fry words hashtables strings
sequences memoize assocs math math.functions locals init sequences memoize assocs math math.functions locals init
namespaces combinators fonts colors core-foundation namespaces combinators fonts colors cache core-foundation
core-foundation.strings core-foundation.attributed-strings core-foundation.strings core-foundation.attributed-strings
core-foundation.utilities core-graphics core-graphics.types core-foundation.utilities core-graphics core-graphics.types
core-text.fonts core-text.utilities ; core-text.fonts core-text.utilities ;
@ -47,7 +47,7 @@ ERROR: not-a-string object ;
CTLineCreateWithAttributedString CTLineCreateWithAttributedString
] with-destructors ; ] with-destructors ;
TUPLE: line font line metrics dim bitmap age refs disposed ; TUPLE: line font line metrics dim bitmap age disposed ;
: compute-line-metrics ( line -- line-metrics ) : compute-line-metrics ( line -- line-metrics )
0 <CGFloat> 0 <CGFloat> 0 <CGFloat> 0 <CGFloat> 0 <CGFloat> 0 <CGFloat>
@ -92,38 +92,16 @@ TUPLE: line font line metrics dim bitmap age refs disposed ;
[ [ line ] dip CTLineDraw ] [ [ line ] dip CTLineDraw ]
} cleave } cleave
] with-bitmap-context ] with-bitmap-context
[ open-font line metrics dim ] dip 0 0 f [ open-font line metrics dim ] dip 0 f
] ]
line boa line boa
] with-destructors ; ] with-destructors ;
M: line dispose* [ font>> CFRelease ] [ line>> CFRelease ] bi ; M: line dispose* [ font>> CFRelease ] [ line>> CFRelease ] bi ;
: ref/unref-line ( line n -- )
'[ _ + ] change-refs 0 >>age drop ;
: ref-line ( line -- ) 1 ref/unref-line ;
: unref-line ( line -- ) -1 ref/unref-line ;
SYMBOL: cached-lines SYMBOL: cached-lines
: cached-line ( font string -- line ) : cached-line ( font string -- line )
cached-lines get [ <line> ] 2cache ; cached-lines get [ <line> ] 2cache ;
CONSTANT: max-line-age 10 [ <cache-assoc> cached-lines set-global ] "core-text" add-init-hook
: age ( obj -- ? )
[ 1+ ] change-age age>> max-line-age >= ;
: age-line ( line -- ? )
#! Outputs t whether the line is dead.
dup refs>> 0 = [ age ] [ drop f ] if ;
: age-assoc ( assoc quot -- assoc' )
'[ nip @ ] assoc-partition
[ values dispose-each ] dip ; inline
: age-lines ( -- )
cached-lines global [ [ age-line ] age-assoc ] change-at ;
[ H{ } clone cached-lines set-global ] "core-text" add-init-hook

View File

@ -0,0 +1 @@
Slava Pestov

View File

@ -0,0 +1,4 @@
! Copyright (C) 2009 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: tools.test opengl.texture-cache ;
IN: opengl.texture-cache.tests

View File

@ -0,0 +1,56 @@
! Copyright (C) 2009 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: accessors assocs cache colors.constants destructors fry
kernel locals opengl opengl.gl ;
IN: opengl.texture-cache
TUPLE: texture texture display-list age disposed ;
: make-texture-display-list ( dim texture -- dlist )
GL_COMPILE [
GL_TEXTURE_2D [
GL_TEXTURE_BIT [
GL_TEXTURE_COORD_ARRAY [
COLOR: white gl-color
GL_TEXTURE_2D swap glBindTexture
init-texture rect-texture-coords
fill-rect-vertices (gl-fill-rect)
GL_TEXTURE_2D 0 glBindTexture
] do-enabled-client-state
] do-attribs
] do-enabled
] make-dlist ;
:: <texture> ( dim bitmap format type -- texture )
dim bitmap format type make-texture
dim over make-texture-display-list 0 f texture boa ;
M: texture dispose*
[ texture>> delete-texture ]
[ display-list>> delete-dlist ] bi ;
TUPLE: texture-cache format type renderer cache disposed ;
: <texture-cache> ( -- cache )
texture-cache new
<cache-assoc> >>cache ;
GENERIC: render-texture ( key renderer -- dim bitmap )
: get-texture ( key texture-cache -- dlist )
dup check-disposed
[ cache>> ] keep
'[
_
[ renderer>> render-texture ]
[ format>> ]
[ type>> ]
tri <texture>
] cache
display-list>> ;
M: texture-cache dispose*
cache>> values dispose-each ;
: purge-texture-cache ( texture-cache -- )
cache>> purge-cache ;

View File

@ -10,7 +10,7 @@ TUPLE: world < track
active? focused? active? focused?
glass glass
title status title status
fonts handle text-handle handle
window-loc ; window-loc ;
: find-world ( gadget -- world/f ) [ world? ] find-parent ; : find-world ( gadget -- world/f ) [ world? ] find-parent ;
@ -42,11 +42,11 @@ M: world request-focus-on ( child gadget -- )
vertical swap new-track vertical swap new-track
t >>root? t >>root?
t >>active? t >>active?
H{ } clone >>fonts
{ 0 0 } >>window-loc { 0 0 } >>window-loc
swap >>status swap >>status
swap >>title swap >>title
swap 1 track-add swap 1 track-add
dup init-text-rendering
dup request-focus ; dup request-focus ;
: <world> ( gadget title status -- world ) : <world> ( gadget title status -- world )

View File

@ -2,64 +2,36 @@
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: assocs accessors alien core-graphics.types core-text USING: assocs accessors alien core-graphics.types core-text
core-text.fonts kernel hashtables namespaces sequences core-text.fonts kernel hashtables namespaces sequences
ui.gadgets.worlds ui.text ui.text.private opengl opengl.gl destructors ui.gadgets.worlds ui.text ui.text.private opengl opengl.gl
combinators core-foundation core-foundation.strings memoize math opengl.texture-cache destructors combinators core-foundation
math.vectors init colors colors.constants ; core-foundation.strings math math.vectors init colors colors.constants
cache arrays ;
IN: ui.text.core-text IN: ui.text.core-text
SINGLETON: core-text-renderer SINGLETON: core-text-renderer
M: core-text-renderer init-text-rendering
<texture-cache>
GL_BGRA_EXT >>format
GL_UNSIGNED_INT_8_8_8_8_REV >>type
core-text-renderer >>renderer
>>text-handle drop ;
M: core-text-renderer string-dim M: core-text-renderer string-dim
[ " " string-dim { 0 1 } v* ] [ cached-line dim>> ] if-empty ; [ " " string-dim { 0 1 } v* ] [ cached-line dim>> ] if-empty ;
TUPLE: rendered-line line texture display-list age disposed ; M: core-text-renderer render-texture
drop first2 cached-line [ dim>> ] [ bitmap>> ] bi ;
: make-line-display-list ( line texture -- dlist )
GL_COMPILE [
GL_TEXTURE_2D [
GL_TEXTURE_BIT [
GL_TEXTURE_COORD_ARRAY [
COLOR: white gl-color
GL_TEXTURE_2D swap glBindTexture
init-texture rect-texture-coords
dim>> fill-rect-vertices (gl-fill-rect)
GL_TEXTURE_2D 0 glBindTexture
] do-enabled-client-state
] do-attribs
] do-enabled
] make-dlist ;
: make-core-graphics-texture ( dim bitmap -- texture )
GL_BGRA_EXT GL_UNSIGNED_INT_8_8_8_8_REV make-texture ;
: <rendered-line> ( line -- texture )
#! Note: we only ref-line if make-texture and make-line-display-list
#! succeed
[
dup [ dim>> ] [ bitmap>> ] bi make-core-graphics-texture
2dup make-line-display-list
0 f \ rendered-line boa
] keep ref-line ;
M: rendered-line dispose*
[ line>> unref-line ]
[ texture>> delete-texture ]
[ display-list>> delete-dlist ] tri ;
: rendered-line ( font string -- rendered-line )
world get fonts>>
[ cached-line <rendered-line> ] 2cache 0 >>age ;
: age-rendered-lines ( world -- )
[ [ age ] age-assoc ] change-fonts drop ;
M: core-text-renderer finish-text-rendering M: core-text-renderer finish-text-rendering
age-rendered-lines age-lines ; text-handle>> purge-texture-cache
cached-lines get purge-cache ;
: rendered-line ( font string -- display-list )
2array world get text-handle>> get-texture ;
M: core-text-renderer draw-string ( font string loc -- ) M: core-text-renderer draw-string ( font string loc -- )
[ [ rendered-line glCallList ] with-translation ;
rendered-line display-list>> glCallList
] with-translation ;
M: core-text-renderer x>offset ( x font string -- n ) M: core-text-renderer x>offset ( x font string -- n )
[ 2drop 0 ] [ [ 2drop 0 ] [
@ -76,7 +48,4 @@ M: core-text-renderer line-metrics ( font string -- metrics )
[ cached-line metrics>> ] [ cached-line metrics>> ]
if-empty ; if-empty ;
M: core-text-renderer free-fonts ( fonts -- )
values dispose-each ;
core-text-renderer font-renderer set-global core-text-renderer font-renderer set-global

View File

@ -8,6 +8,8 @@ IN: ui.text
SYMBOL: font-renderer SYMBOL: font-renderer
HOOK: init-text-rendering font-renderer ( world -- )
HOOK: finish-text-rendering font-renderer ( world -- ) HOOK: finish-text-rendering font-renderer ( world -- )
M: object finish-text-rendering drop ; M: object finish-text-rendering drop ;

View File

@ -9,7 +9,7 @@ IN: ui.tools.listener.tests
\ <interactor> must-infer \ <interactor> must-infer
[ [
[ ] [ <pane> <pane-stream> <interactor> "interactor" set ] unit-test [ ] [ <interactor> <pane> <pane-stream> >>output "interactor" set ] unit-test
[ ] [ "interactor" get register-self ] unit-test [ ] [ "interactor" get register-self ] unit-test
@ -35,7 +35,7 @@ IN: ui.tools.listener.tests
] with-interactive-vocabs ] with-interactive-vocabs
[ [
[ ] [ <pane> <pane-stream> <interactor> "interactor" set ] unit-test [ ] [ <interactor> <pane> <pane-stream> >>output "interactor" set ] unit-test
[ ] [ "interactor" get register-self ] unit-test [ ] [ "interactor" get register-self ] unit-test
@ -56,7 +56,7 @@ IN: ui.tools.listener.tests
] with-interactive-vocabs ] with-interactive-vocabs
! Hang ! Hang
[ ] [ <pane> <pane-stream> <interactor> "interactor" set ] unit-test [ ] [ <interactor> <pane> <pane-stream> >>output "interactor" set ] unit-test
[ ] [ [ "interactor" get stream-read-quot drop ] "A" spawn drop ] unit-test [ ] [ [ "interactor" get stream-read-quot drop ] "A" spawn drop ] unit-test
@ -66,7 +66,7 @@ IN: ui.tools.listener.tests
[ ] [ "interactor" get interactor-eof ] unit-test [ ] [ "interactor" get interactor-eof ] unit-test
[ ] [ <pane> <pane-stream> <interactor> "interactor" set ] unit-test [ ] [ <interactor> <pane> <pane-stream> >>output "interactor" set ] unit-test
: text "Hello world.\nThis is a test." ; : text "Hello world.\nThis is a test." ;
@ -91,7 +91,7 @@ IN: ui.tools.listener.tests
[ t ] [ "promise" get 2 seconds ?promise-timeout text = ] unit-test [ t ] [ "promise" get 2 seconds ?promise-timeout text = ] unit-test
[ ] [ <pane> <pane-stream> <interactor> "interactor" set ] unit-test [ ] [ <interactor> <pane> <pane-stream> >>output "interactor" set ] unit-test
[ ] [ text "interactor" get set-editor-string ] unit-test [ ] [ text "interactor" get set-editor-string ] unit-test
@ -115,7 +115,7 @@ IN: ui.tools.listener.tests
[ ] [ <listener-gadget> "listener" set ] unit-test [ ] [ <listener-gadget> "listener" set ] unit-test
"listener" get [ "listener" get [
<pane> <interactor> "i" set <interactor> <pane> <pane-stream> >>output "i" set
[ t ] [ "i" get interactor? ] unit-test [ t ] [ "i" get interactor? ] unit-test
@ -148,7 +148,7 @@ IN: ui.tools.listener.tests
[ ] [ "listener" get com-end ] unit-test [ ] [ "listener" get com-end ] unit-test
] with-grafted-gadget ] with-grafted-gadget
[ ] [ \ + <pane> <interactor> vocabs>> use-if-necessary ] unit-test [ ] [ \ + <interactor> vocabs>> use-if-necessary ] unit-test
[ ] [ <listener-gadget> "l" set ] unit-test [ ] [ <listener-gadget> "l" set ] unit-test
[ ] [ "l" get com-scroll-up ] unit-test [ ] [ "l" get com-scroll-up ] unit-test

View File

@ -3,8 +3,9 @@
USING: arrays assocs io kernel math models namespaces make dlists USING: arrays assocs io kernel math models namespaces make dlists
deques sequences threads sequences words continuations init call deques sequences threads sequences words continuations init call
combinators hashtables concurrency.flags sets accessors calendar fry combinators hashtables concurrency.flags sets accessors calendar fry
ui.gadgets ui.gadgets.private ui.gadgets.worlds ui.gadgets.tracks destructors ui.gadgets ui.gadgets.private ui.gadgets.worlds
ui.gestures ui.backend ui.render ui.text ui.text.private ; ui.gadgets.tracks ui.gestures ui.backend ui.render ui.text
ui.text.private ;
IN: ui IN: ui
! Assoc mapping aliens to gadgets ! Assoc mapping aliens to gadgets
@ -55,14 +56,12 @@ M: world graft*
: reset-world ( world -- ) : reset-world ( world -- )
#! This is used when a window is being closed, but also #! This is used when a window is being closed, but also
#! when restoring saved worlds on image startup. #! when restoring saved worlds on image startup.
[ fonts>> clear-assoc ] f >>handle unfocus-world ;
[ unfocus-world ]
[ f >>handle drop ] tri ;
: (ungraft-world) ( world -- ) : (ungraft-world) ( world -- )
{ {
[ handle>> select-gl-context ] [ handle>> select-gl-context ]
[ fonts>> free-fonts ] [ text-handle>> dispose ]
[ hand-clicked close-global ] [ hand-clicked close-global ]
[ hand-gadget close-global ] [ hand-gadget close-global ]
} cleave ; } cleave ;
@ -95,7 +94,7 @@ M: world ungraft*
children>> [ restore-gadget ] each ; children>> [ restore-gadget ] each ;
: restore-world ( world -- ) : restore-world ( world -- )
dup reset-world restore-gadget ; [ reset-world ] [ init-text-rendering ] [ restore-gadget ] tri ;
: update-hand ( world -- ) : update-hand ( world -- )
dup hand-world get-global eq? dup hand-world get-global eq?