Increase rendering performance significantly

This commit is contained in:
Cameron Gutman 2016-02-13 15:48:33 -05:00
parent b7032a8957
commit f77979d904
2 changed files with 38 additions and 22 deletions

View File

@ -17,6 +17,8 @@
#include "nacl_io/nacl_io.h"
#include <queue>
#include <Limelight.h>
struct Shader {
@ -32,6 +34,7 @@ class MoonlightInstance : public pp::Instance, public pp::MouseLock {
explicit MoonlightInstance(PP_Instance instance) :
pp::Instance(instance),
pp::MouseLock(this),
m_IsPainting(false),
m_CallbackFactory(this),
m_MouseLocked(false) {
// This function MUST be used otherwise sockets don't work (nacl_io_init() doesn't work!)
@ -70,11 +73,11 @@ class MoonlightInstance : public pp::Instance, public pp::MouseLock {
static Shader CreateProgram(const char* vertexShader, const char* fragmentShader);
static void CreateShader(GLuint program, GLenum type, const char* source, int size);
static void PaintPicture(PP_VideoPicture picture);
void DispatchRendering(int32_t unused);
void PaintFinished(int32_t result);
void DispatchGetPicture(uint32_t unused);
void PictureReady(int32_t result, PP_VideoPicture picture);
void PaintPicture(void);
static void VidDecSetup(int width, int height, int redrawRate, void* context, int drFlags);
static void VidDecCleanup(void);
@ -90,7 +93,8 @@ class MoonlightInstance : public pp::Instance, public pp::MouseLock {
Shader m_Texture2DShader;
Shader m_RectangleArbShader;
Shader m_ExternalOesShader;
PP_VideoPicture m_LastPicture;
std::queue<PP_VideoPicture> m_PendingPictureQueue;
bool m_IsPainting;
double m_LastPadTimestamps[4];
const PPB_Gamepad* m_GamepadApi;

View File

@ -108,7 +108,7 @@ void MoonlightInstance::DidChangeView(const pp::Rect& position,
GL_STATIC_DRAW);
assertNoGLError();
g_Instance->m_Graphics3D.SwapBuffers(g_Instance->m_CallbackFactory.NewCallback(&MoonlightInstance::DispatchRendering));
g_Instance->m_Graphics3D.SwapBuffers(pp::BlockUntilComplete());
}
void MoonlightInstance::VidDecSetup(int width, int height, int redrawRate, void* context, int drFlags) {
@ -128,12 +128,6 @@ void MoonlightInstance::VidDecSetup(int width, int height, int redrawRate, void*
}
void MoonlightInstance::DispatchGetPicture(uint32_t unused) {
/*glClearColor(0.5, 0.5, 0.5, 1);
glClear(GL_COLOR_BUFFER_BIT);
m_Graphics3D.SwapBuffers(
m_CallbackFactory.NewCallback(&MoonlightInstance::DispatchGetPicture));*/
// Queue the initial GetPicture callback on the main thread
g_Instance->m_VideoDecoder->GetPicture(
g_Instance->m_CallbackFactory.NewCallbackWithOutput(&MoonlightInstance::PictureReady));
@ -217,7 +211,18 @@ Shader MoonlightInstance::CreateProgram(const char* vertexShader, const char* fr
return shader;
}
void MoonlightInstance::PaintPicture(PP_VideoPicture picture) {
void MoonlightInstance::PaintPicture(void) {
m_IsPainting = true;
// Free and skip all frames except the latest one
PP_VideoPicture picture;
while (m_PendingPictureQueue.size() > 1) {
picture = m_PendingPictureQueue.front();
m_PendingPictureQueue.pop();
g_Instance->m_VideoDecoder->RecyclePicture(picture);
}
picture = m_PendingPictureQueue.front();
if (picture.texture_target == GL_TEXTURE_2D) {
if (!g_Instance->m_Texture2DShader.program) {
g_Instance->m_Texture2DShader = CreateProgram(k_VertexShader, k_FragmentShader2D);
@ -249,12 +254,21 @@ void MoonlightInstance::PaintPicture(PP_VideoPicture picture) {
glUseProgram(0);
}
g_Instance->m_Graphics3D.SwapBuffers(g_Instance->m_CallbackFactory.NewCallback(&MoonlightInstance::DispatchRendering));
g_Instance->m_Graphics3D.SwapBuffers(
g_Instance->m_CallbackFactory.NewCallback(&MoonlightInstance::PaintFinished));
}
void MoonlightInstance::DispatchRendering(int32_t unused) {
// Paint the image on screen
PaintPicture(m_LastPicture);
void MoonlightInstance::PaintFinished(int32_t result) {
m_IsPainting = false;
// Recycle the picture now that it's been painted
g_Instance->m_VideoDecoder->RecyclePicture(m_PendingPictureQueue.front());
m_PendingPictureQueue.pop();
// Keep painting if we still have frames
if (!m_PendingPictureQueue.empty()) {
PaintPicture();
}
}
void MoonlightInstance::PictureReady(int32_t result, PP_VideoPicture picture) {
@ -262,16 +276,14 @@ void MoonlightInstance::PictureReady(int32_t result, PP_VideoPicture picture) {
return;
}
// Replace the last picture with this one and free the old one
PP_VideoPicture oldPic = m_LastPicture;
m_LastPicture = picture;
if (oldPic.texture_target) {
g_Instance->m_VideoDecoder->RecyclePicture(oldPic);
}
m_PendingPictureQueue.push(picture);
// Queue another callback
g_Instance->m_VideoDecoder->GetPicture(
g_Instance->m_CallbackFactory.NewCallbackWithOutput(&MoonlightInstance::PictureReady));
if (!m_IsPainting) {
PaintPicture();
}
}
DECODER_RENDERER_CALLBACKS MoonlightInstance::s_DrCallbacks = {