From 24cf97b0ae4b649dc219f430e5b6ff6c62e841ee Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Wed, 24 Feb 2016 13:55:35 -0500 Subject: [PATCH 1/5] Only draw frames that are newer than the last frame we drew --- viddec.cpp | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/viddec.cpp b/viddec.cpp index 8b87e14..9e638c5 100644 --- a/viddec.cpp +++ b/viddec.cpp @@ -13,6 +13,8 @@ static unsigned char* s_DecodeBuffer; static unsigned int s_DecodeBufferLength; static int s_LastTextureType; static int s_LastTextureId; +static int s_NextDecodeFrameNumber; +static int s_LastDisplayFrameNumber; static unsigned char s_LastSps[256]; static unsigned char s_LastPps[256]; static unsigned int s_LastSpsLength; @@ -146,6 +148,8 @@ void MoonlightInstance::VidDecSetup(int width, int height, int redrawRate, void* s_LastTextureId = 0; s_LastSpsLength = 0; s_LastPpsLength = 0; + s_NextDecodeFrameNumber = 0; + s_LastDisplayFrameNumber = 0; g_Instance->m_VideoDecoder->Initialize(g_Instance->m_Graphics3D, PP_VIDEOPROFILE_H264HIGH, @@ -284,7 +288,7 @@ int MoonlightInstance::VidDecSubmitDecodeUnit(PDECODE_UNIT decodeUnit) { } // Start the decoding - g_Instance->m_VideoDecoder->Decode(0, offset, s_DecodeBuffer, pp::BlockUntilComplete()); + g_Instance->m_VideoDecoder->Decode(s_NextDecodeFrameNumber++, offset, s_DecodeBuffer, pp::BlockUntilComplete()); return DR_OK; } @@ -415,12 +419,21 @@ void MoonlightInstance::PictureReady(int32_t result, PP_VideoPicture picture) { return; } - m_PendingPictureQueue.push(picture); + // Ensure we only push newer frames onto the display queue + if (picture.decode_id > s_LastDisplayFrameNumber) { + m_PendingPictureQueue.push(picture); + s_LastDisplayFrameNumber = picture.decode_id; + } + else { + // This picture is older than the last one we displayed. Discard + // it without displaying. + g_Instance->m_VideoDecoder->RecyclePicture(picture); + } g_Instance->m_VideoDecoder->GetPicture( g_Instance->m_CallbackFactory.NewCallbackWithOutput(&MoonlightInstance::PictureReady)); - if (!m_IsPainting) { + if (!m_IsPainting && !m_PendingPictureQueue.empty()) { PaintPicture(); } } From e7b45e5b6c45dadb806953a3732c4ea5ce3f2d9e Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Thu, 25 Feb 2016 22:48:22 -0500 Subject: [PATCH 2/5] Set the graphics context size using the width and height of the stream instead of the initial size of the NaCl element. This closes issue #16 --- index.html | 2 +- main.cpp | 3 +++ moonlight.hpp | 5 +---- viddec.cpp | 21 ++++----------------- 4 files changed, 9 insertions(+), 22 deletions(-) diff --git a/index.html b/index.html index d52cdb2..49e92cf 100644 --- a/index.html +++ b/index.html @@ -8,7 +8,7 @@ - +
diff --git a/main.cpp b/main.cpp index 938f765..8631b7f 100644 --- a/main.cpp +++ b/main.cpp @@ -174,6 +174,9 @@ void MoonlightInstance::handleStartStream(std::string startStreamMessage) { m_StreamConfig.audioConfiguration = AUDIO_CONFIGURATION_STEREO; m_ServerMajorVersion = 5; + + // Initialize the rendering surface before starting the connection + InitializeRenderingSurface(m_StreamConfig.width, m_StreamConfig.height); // Store the host from the start message m_Host = splitString.at(1); diff --git a/moonlight.hpp b/moonlight.hpp index b3f36af..e35fd98 100644 --- a/moonlight.hpp +++ b/moonlight.hpp @@ -76,9 +76,6 @@ class MoonlightInstance : public pp::Instance, public pp::MouseLock { void OnConnectionStarted(uint32_t error); void StopConnection(); - void DidChangeView(const pp::Rect& position, - const pp::Rect& clip_ignored); - static void* ConnectionThreadFunc(void* context); static void* GamepadThreadFunc(void* context); static void* StopThreadFunc(void* context); @@ -97,6 +94,7 @@ class MoonlightInstance : public pp::Instance, public pp::MouseLock { void DispatchGetPicture(uint32_t unused); void PictureReady(int32_t result, PP_VideoPicture picture); void PaintPicture(void); + void InitializeRenderingSurface(int width, int height); static void VidDecSetup(int width, int height, int redrawRate, void* context, int drFlags); static void VidDecCleanup(void); @@ -121,7 +119,6 @@ class MoonlightInstance : public pp::Instance, public pp::MouseLock { pp::Graphics3D m_Graphics3D; pp::VideoDecoder* m_VideoDecoder; - pp::Size m_ViewSize; Shader m_Texture2DShader; Shader m_RectangleArbShader; Shader m_ExternalOesShader; diff --git a/viddec.cpp b/viddec.cpp index 9e638c5..f5d94d7 100644 --- a/viddec.cpp +++ b/viddec.cpp @@ -70,20 +70,7 @@ void MoonlightInstance::DidChangeFocus(bool got_focus) { } } -void MoonlightInstance::DidChangeView(const pp::Rect& position, - const pp::Rect& clip) { - - if (position.width() == 0 || position.height() == 0) { - return; - } - if (m_ViewSize.width()) { - assert(position.size() == m_ViewSize); - return; - } - - m_ViewSize = position.size(); - printf("View size: %dx%d\n", m_ViewSize.width(), m_ViewSize.height()); - +void MoonlightInstance::InitializeRenderingSurface(int width, int height) { if (!glInitializePPAPI(pp::Module::Get()->get_browser_interface())) { return; } @@ -97,8 +84,8 @@ void MoonlightInstance::DidChangeView(const pp::Rect& position, PP_GRAPHICS3DATTRIB_STENCIL_SIZE, 0, PP_GRAPHICS3DATTRIB_SAMPLES, 0, PP_GRAPHICS3DATTRIB_SAMPLE_BUFFERS, 0, - PP_GRAPHICS3DATTRIB_WIDTH, position.size().width(), - PP_GRAPHICS3DATTRIB_HEIGHT, position.size().height(), + PP_GRAPHICS3DATTRIB_WIDTH, width, + PP_GRAPHICS3DATTRIB_HEIGHT, height, PP_GRAPHICS3DATTRIB_NONE }; g_Instance->m_Graphics3D = pp::Graphics3D(this, contextAttributes); @@ -114,7 +101,7 @@ void MoonlightInstance::DidChangeView(const pp::Rect& position, glDisable(GL_DITHER); - glViewport(0, 0, m_ViewSize.width(), m_ViewSize.height()); + glViewport(0, 0, width, height); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); From 4f6c547e476fd822d22a9634be6d010408796f8c Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Fri, 26 Feb 2016 14:43:20 -0500 Subject: [PATCH 3/5] Fix scrolling behavior by accumulating partial ticks --- input.cpp | 15 +++++++++++++-- moonlight.hpp | 4 +++- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/input.cpp b/input.cpp index abb33da..e9ca6bc 100644 --- a/input.cpp +++ b/input.cpp @@ -112,14 +112,25 @@ bool MoonlightInstance::HandleInputEvent(const pp::InputEvent& event) { } case PP_INPUTEVENT_TYPE_WHEEL: { + signed char fullTicks; + if (!m_MouseLocked) { return false; } pp::WheelInputEvent wheelEvent(event); - // FIXME: Handle fractional scroll ticks - LiSendScrollEvent((signed char) wheelEvent.GetTicks().y()); + // Accumulate the current tick value + m_AccumulatedTicks += wheelEvent.GetTicks().y(); + + // Compute the number of full ticks + fullTicks = (signed char) m_AccumulatedTicks; + + // Send a scroll event if we've completed a full tick + if (fullTicks != 0) { + LiSendScrollEvent(fullTicks); + m_AccumulatedTicks -= fullTicks; + } return true; } diff --git a/moonlight.hpp b/moonlight.hpp index e35fd98..386fd09 100644 --- a/moonlight.hpp +++ b/moonlight.hpp @@ -44,7 +44,8 @@ class MoonlightInstance : public pp::Instance, public pp::MouseLock { m_CallbackFactory(this), m_MouseLocked(false), m_KeyModifiers(0), - m_WaitingForAllModifiersUp(false) { + m_WaitingForAllModifiersUp(false), + m_AccumulatedTicks(0) { // This function MUST be used otherwise sockets don't work (nacl_io_init() doesn't work!) nacl_io_init_ppapi(pp_instance(), pp::Module::Get()->get_browser_interface()); @@ -135,6 +136,7 @@ class MoonlightInstance : public pp::Instance, public pp::MouseLock { bool m_MouseLocked; char m_KeyModifiers; bool m_WaitingForAllModifiersUp; + float m_AccumulatedTicks; }; extern MoonlightInstance* g_Instance; From abe66c7e219dc0079b9c5b3f55d54f88df284245 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Fri, 26 Feb 2016 17:20:10 -0500 Subject: [PATCH 4/5] Set some nicer Graphics3D context attributes to allow the GLES backend more flexibility when choosing a context --- viddec.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/viddec.cpp b/viddec.cpp index f5d94d7..39c2168 100644 --- a/viddec.cpp +++ b/viddec.cpp @@ -76,20 +76,21 @@ void MoonlightInstance::InitializeRenderingSurface(int width, int height) { } int32_t contextAttributes[] = { - PP_GRAPHICS3DATTRIB_ALPHA_SIZE, 8, PP_GRAPHICS3DATTRIB_BLUE_SIZE, 8, PP_GRAPHICS3DATTRIB_GREEN_SIZE, 8, PP_GRAPHICS3DATTRIB_RED_SIZE, 8, - PP_GRAPHICS3DATTRIB_DEPTH_SIZE, 0, - PP_GRAPHICS3DATTRIB_STENCIL_SIZE, 0, - PP_GRAPHICS3DATTRIB_SAMPLES, 0, - PP_GRAPHICS3DATTRIB_SAMPLE_BUFFERS, 0, PP_GRAPHICS3DATTRIB_WIDTH, width, PP_GRAPHICS3DATTRIB_HEIGHT, height, PP_GRAPHICS3DATTRIB_NONE }; g_Instance->m_Graphics3D = pp::Graphics3D(this, contextAttributes); + int32_t swapBehaviorAttribute[] = { + PP_GRAPHICS3DATTRIB_SWAP_BEHAVIOR, PP_GRAPHICS3DATTRIB_BUFFER_DESTROYED, + PP_GRAPHICS3DATTRIB_NONE + }; + g_Instance->m_Graphics3D.SetAttribs(swapBehaviorAttribute); + if (!BindGraphics(m_Graphics3D)) { fprintf(stderr, "Unable to bind 3d context!\n"); m_Graphics3D = pp::Graphics3D(); From 1aff99d5e8106a241ee5f3c3f1975a5b146e9d4a Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Fri, 26 Feb 2016 22:26:36 -0500 Subject: [PATCH 5/5] Fix the accent menu showing up on OS X. This closes #1 --- moonlight.hpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/moonlight.hpp b/moonlight.hpp index 386fd09..1228746 100644 --- a/moonlight.hpp +++ b/moonlight.hpp @@ -5,6 +5,7 @@ #include "ppapi/cpp/graphics_3d.h" #include "ppapi/cpp/video_decoder.h" #include "ppapi/cpp/audio.h" +#include "ppapi/cpp/text_input_controller.h" #include "ppapi/c/ppb_gamepad.h" #include "ppapi/c/pp_input_event.h" @@ -50,6 +51,8 @@ class MoonlightInstance : public pp::Instance, public pp::MouseLock { nacl_io_init_ppapi(pp_instance(), pp::Module::Get()->get_browser_interface()); LiInitializeStreamConfiguration(&m_StreamConfig); + + pp::TextInputController(this).SetTextInputType(PP_TEXTINPUT_TYPE_NONE); m_GamepadApi = static_cast(pp::Module::Get()->GetBrowserInterface(PPB_GAMEPAD_INTERFACE)); }