SHARE
TWEET

geoff

a guest Jun 12th, 2019 59 in 25 days
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. From 88fd0e9ec87573cbf63438ea1335564aa4664752 Mon Sep 17 00:00:00 2001
  2. From: Geoffrey McRae <geoff@hostfission.com>
  3. Date: Wed, 12 Jun 2019 19:22:35 +1000
  4. Subject: [PATCH] [client] improve texture streaming support and performance
  5.  
  6. ---
  7.  VERSION                        |   2 +-
  8.  client/renderers/EGL/desktop.c |  36 ++++++++--
  9.  client/renderers/EGL/texture.c | 128 +++++++++++++++++++--------------
  10.  3 files changed, 107 insertions(+), 59 deletions(-)
  11.  
  12. diff --git a/VERSION b/VERSION
  13. index 9355885..4b8ba9b 100644
  14. --- a/VERSION
  15. +++ b/VERSION
  16. @@ -1 +1 @@
  17. -B1-rc5-8-ge3343cbd01+1
  18. \ No newline at end of file
  19. +B1-rc5-9-g6d24dd52d6+1
  20. \ No newline at end of file
  21. diff --git a/client/renderers/EGL/desktop.c b/client/renderers/EGL/desktop.c
  22. index ffd1968..8d6c938 100644
  23. --- a/client/renderers/EGL/desktop.c
  24. +++ b/client/renderers/EGL/desktop.c
  25. @@ -60,6 +60,7 @@ struct EGL_Desktop
  26.    unsigned int         width, height;
  27.    unsigned int         pitch;
  28.    const uint8_t      * data;
  29. +  LG_Lock              updateLock;
  30.    bool                 update;
  31.  
  32.    // night vision
  33. @@ -70,6 +71,7 @@ struct EGL_Desktop
  34.  
  35.  // forwards
  36.  void egl_desktop_toggle_nv(SDL_Scancode key, void * opaque);
  37. +bool egl_int_desktop_perform_update(EGL_Desktop * desktop, const bool sourceChanged);
  38.  
  39.  static bool egl_init_desktop_shader(
  40.    struct DesktopShader * shader,
  41. @@ -139,6 +141,7 @@ bool egl_desktop_init(EGL_Desktop ** desktop)
  42.  
  43.    egl_model_set_default((*desktop)->model);
  44.    egl_model_set_texture((*desktop)->model, (*desktop)->texture);
  45. +  LG_LOCK_INIT((*desktop)->updateLock);
  46.  
  47.    (*desktop)->kbNV = app_register_keybind(SDL_SCANCODE_N, egl_desktop_toggle_nv, *desktop);
  48.  
  49. @@ -165,6 +168,7 @@ void egl_desktop_free(EGL_Desktop ** desktop)
  50.    if (!*desktop)
  51.      return;
  52.  
  53. +  LG_LOCK_FREE((*desktop)->updateLock);
  54.    egl_texture_free(&(*desktop)->texture              );
  55.    egl_shader_free (&(*desktop)->shader_generic.shader);
  56.    egl_shader_free (&(*desktop)->shader_yuv.shader    );
  57. @@ -178,6 +182,11 @@ void egl_desktop_free(EGL_Desktop ** desktop)
  58.  
  59.  bool egl_desktop_prepare_update(EGL_Desktop * desktop, const bool sourceChanged, const LG_RendererFormat format, const uint8_t * data)
  60.  {
  61. +  LG_LOCK(desktop->updateLock);
  62. +
  63. +  desktop->data   = data;
  64. +  desktop->update = true;
  65. +
  66.    if (sourceChanged)
  67.    {
  68.      switch(format.type)
  69. @@ -204,21 +213,24 @@ bool egl_desktop_prepare_update(EGL_Desktop * desktop, const bool sourceChanged,
  70.  
  71.        default:
  72.          DEBUG_ERROR("Unsupported frame format");
  73. +        LG_UNLOCK(desktop->updateLock);
  74.          return false;
  75.      }
  76.  
  77.      desktop->width  = format.width;
  78.      desktop->height = format.height;
  79.      desktop->pitch  = format.pitch;
  80. -  }
  81.  
  82. -  desktop->data   = data;
  83. -  desktop->update = true;
  84. +    // the copy must be deferred as we need to issue GL commands and this
  85. +    // function is not operating inside the thread that owns the GL context
  86. +    LG_UNLOCK(desktop->updateLock);
  87. +    return true;
  88. +  }
  89.  
  90. -  return true;
  91. +  return egl_int_desktop_perform_update(desktop, false);
  92.  }
  93.  
  94. -bool egl_desktop_perform_update(EGL_Desktop * desktop, const bool sourceChanged)
  95. +bool egl_int_desktop_perform_update(EGL_Desktop * desktop, const bool sourceChanged)
  96.  {
  97.    if (sourceChanged)
  98.    {
  99. @@ -232,23 +244,37 @@ bool egl_desktop_perform_update(EGL_Desktop * desktop, const bool sourceChanged)
  100.      ))
  101.      {
  102.        DEBUG_ERROR("Failed to setup the desktop texture");
  103. +
  104. +      LG_UNLOCK(desktop->updateLock);
  105.        return false;
  106.      }
  107.    }
  108.  
  109.    if (!desktop->update)
  110. +  {
  111. +    LG_UNLOCK(desktop->updateLock);
  112.      return true;
  113. +  }
  114.  
  115.    if (!egl_texture_update(desktop->texture, desktop->data))
  116.    {
  117.      DEBUG_ERROR("Failed to update the desktop texture");
  118. +    LG_UNLOCK(desktop->updateLock);
  119.      return false;
  120.    }
  121.  
  122.    desktop->update = false;
  123. +
  124. +  LG_UNLOCK(desktop->updateLock);
  125.    return true;
  126.  }
  127.  
  128. +bool egl_desktop_perform_update(EGL_Desktop * desktop, const bool sourceChanged)
  129. +{
  130. +  LG_LOCK(desktop->updateLock);
  131. +  return egl_int_desktop_perform_update(desktop, sourceChanged);
  132. +}
  133. +
  134.  void egl_desktop_render(EGL_Desktop * desktop, const float x, const float y, const float scaleX, const float scaleY, const bool nearest)
  135.  {
  136.    if (!desktop->shader)
  137. diff --git a/client/renderers/EGL/texture.c b/client/renderers/EGL/texture.c
  138. index a38374a..43b51bf 100644
  139. --- a/client/renderers/EGL/texture.c
  140. +++ b/client/renderers/EGL/texture.c
  141. @@ -43,11 +43,14 @@ struct EGL_Texture
  142.    GLenum   dataType;
  143.  
  144.    bool   hasPBO;
  145. -  GLuint pbo[2];
  146. -  int    pboIndex;
  147. +  GLuint pbo;
  148. +  int    pboWIndex;
  149. +  int    pboRIndex;
  150. +  int    pboCount;
  151.    bool   needsUpdate;
  152.    size_t pboBufferSize;
  153. -  void * pboMap[2];
  154. +  GLsync pboSync[3];
  155. +  void * pboMap[3];
  156.  };
  157.  
  158.  bool egl_texture_init(EGL_Texture ** texture)
  159. @@ -77,13 +80,10 @@ void egl_texture_free(EGL_Texture ** texture)
  160.  
  161.    if ((*texture)->hasPBO)
  162.    {
  163. -    for(int i = 0; i < 2; ++i)
  164. -    {
  165. -      glBindBuffer(GL_PIXEL_UNPACK_BUFFER, (*texture)->pbo[i]);
  166. -      glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
  167. -    }
  168. +    glBindBuffer(GL_PIXEL_UNPACK_BUFFER, (*texture)->pbo);
  169. +    glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
  170.      glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
  171. -    glDeleteBuffers(2, (*texture)->pbo);
  172. +    glDeleteBuffers(1, &(*texture)->pbo);
  173.    }
  174.  
  175.    free(*texture);
  176. @@ -192,44 +192,44 @@ bool egl_texture_setup(EGL_Texture * texture, enum EGL_PixelFormat pixFmt, size_
  177.      if (texture->hasPBO)
  178.      {
  179.        // release old PBOs and delete the buffers
  180. -      for(int i = 0; i < 2; ++i)
  181. -      {
  182. -        glBindBuffer(GL_PIXEL_UNPACK_BUFFER, texture->pbo[i]);
  183. -        glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
  184. -      }
  185. -      glDeleteBuffers(2, texture->pbo);
  186. +      glBindBuffer(GL_PIXEL_UNPACK_BUFFER, texture->pbo);
  187. +      glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
  188. +      glDeleteBuffers(1, &texture->pbo);
  189.      }
  190.  
  191. -    glGenBuffers(2, texture->pbo);
  192. +    glGenBuffers(1, &texture->pbo);
  193.      texture->hasPBO = true;
  194. -    for(int i = 0; i < 2; ++i)
  195. +
  196. +    glBindBuffer(GL_PIXEL_UNPACK_BUFFER, texture->pbo);
  197. +    glBufferStorage(
  198. +      GL_PIXEL_UNPACK_BUFFER,
  199. +      texture->pboBufferSize * 3,
  200. +      NULL,
  201. +      GL_MAP_PERSISTENT_BIT |
  202. +      GL_MAP_WRITE_BIT
  203. +    );
  204. +
  205. +    texture->pboMap[0] = glMapBufferRange(
  206. +      GL_PIXEL_UNPACK_BUFFER,
  207. +      0,
  208. +      texture->pboBufferSize * 3,
  209. +      GL_MAP_PERSISTENT_BIT        |
  210. +      GL_MAP_WRITE_BIT             |
  211. +      GL_MAP_UNSYNCHRONIZED_BIT    |
  212. +      GL_MAP_INVALIDATE_BUFFER_BIT |
  213. +      GL_MAP_INVALIDATE_RANGE_BIT  |
  214. +      GL_MAP_FLUSH_EXPLICIT_BIT
  215. +    );
  216. +
  217. +    if (!texture->pboMap[0])
  218.      {
  219. -      glBindBuffer(GL_PIXEL_UNPACK_BUFFER, texture->pbo[i]);
  220. -      glBufferStorage(
  221. -        GL_PIXEL_UNPACK_BUFFER,
  222. -        texture->pboBufferSize,
  223. -        NULL,
  224. -        GL_MAP_PERSISTENT_BIT |
  225. -        GL_MAP_WRITE_BIT      |
  226. -        GL_MAP_COHERENT_BIT
  227. -      );
  228. +      DEBUG_ERROR("glMapBufferRange failed %lu bytes", texture->pboBufferSize);
  229. +      return false;
  230. +    }
  231.  
  232. -      texture->pboMap[i] = glMapBufferRange(
  233. -        GL_PIXEL_UNPACK_BUFFER,
  234. -        0,
  235. -        texture->pboBufferSize,
  236. -        GL_MAP_PERSISTENT_BIT        |
  237. -        GL_MAP_WRITE_BIT             |
  238. -        GL_MAP_UNSYNCHRONIZED_BIT    |
  239. -        GL_MAP_INVALIDATE_BUFFER_BIT
  240. -      );
  241. +    for(int i = 1; i < 3; ++i)
  242. +      texture->pboMap[i] = texture->pboMap[0] + i * texture->pboBufferSize;
  243.  
  244. -      if (!texture->pboMap[i])
  245. -      {
  246. -        DEBUG_ERROR("glMapBufferRange failed for %d of %lu bytes", i, texture->pboBufferSize);
  247. -        return false;
  248. -      }
  249. -    }
  250.      glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
  251.    }
  252.  
  253. @@ -240,17 +240,15 @@ bool egl_texture_update(EGL_Texture * texture, const uint8_t * buffer)
  254.  {
  255.    if (texture->streaming)
  256.    {
  257. -    if (texture->needsUpdate)
  258. +    if (texture->pboCount < 3)
  259.      {
  260. -      DEBUG_ERROR("Previous frame was not consumed");
  261. -      return false;
  262. +      if (++texture->pboWIndex == 3)
  263. +        texture->pboWIndex = 0;
  264. +      ++texture->pboCount;
  265.      }
  266.  
  267. -    if (++texture->pboIndex == 2)
  268. -      texture->pboIndex = 0;
  269. -
  270.      /* update the GPU buffer */
  271. -    memcpy(texture->pboMap[texture->pboIndex], buffer, texture->pboBufferSize);
  272. +    memcpy(texture->pboMap[texture->pboWIndex], buffer, texture->pboBufferSize);
  273.  
  274.      texture->needsUpdate = true;
  275.    }
  276. @@ -272,18 +270,42 @@ void egl_texture_bind(EGL_Texture * texture)
  277.  {
  278.    if (texture->streaming && texture->needsUpdate)
  279.    {
  280. -    glBindBuffer(GL_PIXEL_UNPACK_BUFFER, texture->pbo[texture->pboIndex]);
  281. +    if (!texture->pboCount)
  282. +    {
  283. +      // no update, so just bind
  284. +      for(int i = 0; i < texture->textureCount; ++i)
  285. +        glBindTexture(GL_TEXTURE_2D, texture->textures[i]);
  286. +      return;
  287. +    }
  288. +
  289. +    glBindBuffer(GL_PIXEL_UNPACK_BUFFER, texture->pbo);
  290. +    glFlushMappedBufferRange(
  291. +      GL_PIXEL_UNPACK_BUFFER,
  292. +      texture->pboBufferSize * texture->pboRIndex,
  293. +      texture->pboBufferSize
  294. +    );
  295. +
  296.      for(int i = 0; i < texture->textureCount; ++i)
  297.      {
  298.        glBindTexture(GL_TEXTURE_2D, texture->textures[i]);
  299. -      glPixelStorei(GL_UNPACK_ROW_LENGTH, texture->planes[i][2]);
  300. -      glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texture->planes[i][0], texture->planes[i][1],
  301. -          texture->format, texture->dataType, (const void *)texture->offsets[i]);
  302. +      glPixelStorei(GL_UNPACK_ROW_LENGTH , texture->planes[i][2]);
  303. +      glTexSubImage2D(
  304. +        GL_TEXTURE_2D, 0,
  305. +        0,
  306. +        0,
  307. +        texture->planes[i][0],
  308. +        texture->planes[i][1],
  309. +        texture->format,
  310. +        texture->dataType,
  311. +        (const void *)texture->offsets[i] + texture->pboBufferSize * texture->pboRIndex
  312. +      );
  313.      }
  314.      glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
  315.      glBindTexture(GL_TEXTURE_2D, 0);
  316.  
  317. -    texture->needsUpdate = false;
  318. +    if (++texture->pboRIndex == 3)
  319. +      texture->pboRIndex = 0;
  320. +    --texture->pboCount;
  321.    }
  322.  
  323.    for(int i = 0; i < texture->textureCount; ++i)
  324. --
  325. 2.20.1
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top