Skip to content

Commit

Permalink
[WIP] Bugfix / Performance: Memory leak - always allocating new memor…
Browse files Browse the repository at this point in the history
…y for font characters (mono#64)

Bugfix / Performance: Memory leak - always allocating new memory for font characters
  • Loading branch information
bryphe authored Nov 24, 2018
1 parent 4d5df2e commit 4c126a6
Show file tree
Hide file tree
Showing 9 changed files with 102 additions and 24 deletions.
1 change: 1 addition & 0 deletions .ci/esy-build-steps.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ steps:
continueOnError: true
- script: esy install
- script: esy build
- script: esy b dune runtest
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,16 @@
"@opam/lwt_ppx": "^1.1.0",
"@opam/js_of_ocaml": "*",
"@opam/js_of_ocaml-lwt": "*",
"@opam/dune": "^1.5.0",
"flex": "^1.2.2",
"@opam/js_of_ocaml-compiler": "*"
"@opam/js_of_ocaml-compiler": "*",
"rejest": "^1.2.0"
},
"peerDependencies": {
"ocaml": "~4.6.0"
},
"devDependencies": {
"ocaml": "~4.6.0",
"@opam/merlin": "*"
"@opam/merlin": "*",
"@opam/dune": "^1.5.0"
}
}
38 changes: 24 additions & 14 deletions src/Core/Revery_Core.re
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,30 @@ module Event = Reactify.Event;

module Performance = Performance;

module Memoize = {
type t('a, 'b) = 'a => 'b;

let make = (f: t('a, 'b)): t('a, 'b) => {
let tbl: Hashtbl.t('a, 'b) = Hashtbl.create(16);

let ret = (arg: 'a) => {
let cv = Hashtbl.find_opt(tbl, arg);
switch(cv) {
| Some(x) => x
| None =>
let r = f(arg);
Hashtbl.add(tbl, arg, r);
r;
}
};
ret;
};
}

module Lazy = {
type innerFunc('a) = unit => 'a;

let make = (f: innerFunc('a)): innerFunc('a) => {
let v: ref(option('a)) = ref(None);

let ret = () =>
switch (v^) {
| Some(x) => x
| None =>
let out = f();
v := Some(out);
out;
};
ret;
type t('a) = Memoize.t(unit, 'a);

let make = (f: t('a)): t('a) => {
Memoize.make(f);
};
};
18 changes: 12 additions & 6 deletions src/UI/FontRenderer.re
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
open Reglfw.Glfw;
open Fontkit;

let getGlyph = (font: Fontkit.fk_face, codepoint: int) =>
/* TODO: Cache */
Fontkit.renderGlyph(font, codepoint);
open Revery_Core;

let getTexture = (font: Fontkit.fk_face, codepoint: int) => {

let _getGlyph = Memoize.make(((font: Fontkit.fk_face, codepoint: int)) =>
Fontkit.renderGlyph(font, codepoint));

let getGlyph = (font: Fontkit.fk_face, codepoint: int) => _getGlyph((font, codepoint));


let _getTexture = ((font: Fontkit.fk_face, codepoint: int)) => {
let glyph = getGlyph(font, codepoint);

let {image, _} = glyph;

/* TODO: */
/* - Cache textures */
/* - Create texture atlas */
glPixelStorei(GL_PACK_ALIGNMENT, 1);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
Expand All @@ -26,6 +29,9 @@ let getTexture = (font: Fontkit.fk_face, codepoint: int) => {
texture;
};

let _memoizedGetTexture = Memoize.make(_getTexture);
let getTexture = (font: Fontkit.fk_face, codepoint: int) => _memoizedGetTexture((font, codepoint));

type dimensions = {
width: int,
height: int,
Expand Down
7 changes: 6 additions & 1 deletion src/UI/TextNode.re
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ module LayoutTypes = Layout.LayoutTypes;

open Fontkit;
open Reglm;
open Reglfw;
open Revery_Core;

open ViewNode;
Expand Down Expand Up @@ -55,7 +56,11 @@ class textNode (name: string, text: string) = {

let {width, height, bearingX, bearingY, advance, _} = glyph;

let _ = FontRenderer.getTexture(font, s.codepoint);
Glfw.glPixelStorei(GL_PACK_ALIGNMENT, 1);
Glfw.glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

let texture = FontRenderer.getTexture(font, s.codepoint);
Glfw.glBindTexture(GL_TEXTURE_2D, texture);
/* TODO: Bind texture */

let glyphTransform = Mat4.create();
Expand Down
39 changes: 39 additions & 0 deletions test/Core/MemoizeTests.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
open Rejest;

open Revery_Core;

test("Memoize", () => {
test("Simple memoization", () => {
let v = ref(0);
let testFunction =
Memoize.make(_a => {
v := v^ + 1;
v^;
});

let t0 = testFunction(0);
let t1 = testFunction(0);

expect(t0).toEqual(1);
expect(t1).toEqual(1);
});

test("Memoizes multiple arguments", () => {
let v = ref(0);
let testFunction =
Memoize.make(a => {
v := v^ + 1;
a ++ string_of_int(v^);
});

let t0 = testFunction("a");
let t1 = testFunction("b");
let t2 = testFunction("a");
let t3 = testFunction("b");

expect(t0).toEqual("a1");
expect(t1).toEqual("b2");
expect(t2).toEqual("a1");
expect(t3).toEqual("b2");
});
});
5 changes: 5 additions & 0 deletions test/Core/dune
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
(library
(name Revery_Core_Test)
(library_flags (-linkall))
(modules (:standard))
(libraries Revery_Core rejest))
1 change: 1 addition & 0 deletions test/TestRunner.re
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Rejest.run();
10 changes: 10 additions & 0 deletions test/dune
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
(executable
(name TestRunner)
(libraries
rejest
Revery_Core_Test
))

(alias
(name runtest)
(action (run ./TestRunner.exe)))

0 comments on commit 4c126a6

Please sign in to comment.