mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-25 16:55:07 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into 20622
This commit is contained in:
commit
a82bf1d407
16 changed files with 154 additions and 141 deletions
|
@ -3389,14 +3389,10 @@ void Application::renderRearViewMirror(RenderArgs* renderArgs, const QRect& regi
|
|||
// set the bounds of rear mirror view
|
||||
gpu::Vec4i viewport;
|
||||
if (billboard) {
|
||||
QSize size = DependencyManager::get<FramebufferCache>()->getFrameBufferSize();
|
||||
viewport = gpu::Vec4i(0, 0, region.width(), region.height());
|
||||
} else {
|
||||
// if not rendering the billboard, the region is in device independent coordinates; must convert to device
|
||||
QSize size = DependencyManager::get<FramebufferCache>()->getFrameBufferSize();
|
||||
float ratio = (float)QApplication::desktop()->windowHandle()->devicePixelRatio() * getRenderResolutionScale();
|
||||
int x = region.x() * ratio;
|
||||
int y = region.y() * ratio;
|
||||
int width = region.width() * ratio;
|
||||
int height = region.height() * ratio;
|
||||
viewport = gpu::Vec4i(0, 0, width, height);
|
||||
|
|
|
@ -252,8 +252,6 @@ Menu::Menu() {
|
|||
avatar, SLOT(updateMotionBehavior()));
|
||||
|
||||
MenuWrapper* viewMenu = addMenu("View");
|
||||
|
||||
addActionToQMenuAndActionHash(viewMenu, MenuOption::ReloadContent, 0, qApp, SLOT(reloadResourceCaches()));
|
||||
|
||||
addCheckableActionToQMenuAndActionHash(viewMenu,
|
||||
MenuOption::Fullscreen,
|
||||
|
@ -489,6 +487,7 @@ Menu::Menu() {
|
|||
#endif
|
||||
|
||||
MenuWrapper* networkMenu = developerMenu->addMenu("Network");
|
||||
addActionToQMenuAndActionHash(networkMenu, MenuOption::ReloadContent, 0, qApp, SLOT(reloadResourceCaches()));
|
||||
addCheckableActionToQMenuAndActionHash(networkMenu, MenuOption::DisableNackPackets, 0, false,
|
||||
qApp->getEntityEditPacketSender(),
|
||||
SLOT(toggleNackPackets()));
|
||||
|
|
|
@ -462,8 +462,8 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) {
|
|||
const float LOOKING_AT_ME_ALPHA_START = 0.8f;
|
||||
const float LOOKING_AT_ME_DURATION = 0.5f; // seconds
|
||||
quint64 now = usecTimestampNow();
|
||||
float alpha = LOOKING_AT_ME_ALPHA_START
|
||||
* (1.0f - ((float)(usecTimestampNow() - getHead()->getLookingAtMeStarted()))
|
||||
float alpha = LOOKING_AT_ME_ALPHA_START
|
||||
* (1.0f - ((float)(now - getHead()->getLookingAtMeStarted()))
|
||||
/ (LOOKING_AT_ME_DURATION * (float)USECS_PER_SECOND));
|
||||
if (alpha > 0.0f) {
|
||||
QSharedPointer<NetworkGeometry> geometry = getHead()->getFaceModel().getGeometry();
|
||||
|
|
|
@ -1290,7 +1290,6 @@ bool MyAvatar::shouldRenderHead(const RenderArgs* renderArgs) const {
|
|||
|
||||
void MyAvatar::updateOrientation(float deltaTime) {
|
||||
// Smoothly rotate body with arrow keys
|
||||
float driveLeft = _driveKeys[ROT_LEFT] - _driveKeys[ROT_RIGHT];
|
||||
float targetSpeed = (_driveKeys[ROT_LEFT] - _driveKeys[ROT_RIGHT]) * YAW_SPEED;
|
||||
if (targetSpeed != 0.0f) {
|
||||
const float ROTATION_RAMP_TIMESCALE = 0.1f;
|
||||
|
|
|
@ -91,13 +91,12 @@ private:
|
|||
|
||||
int _leftBlinkIndex;
|
||||
int _rightBlinkIndex;
|
||||
int _leftEyeOpenIndex;
|
||||
int _rightEyeOpenIndex;
|
||||
|
||||
int _leftEyeDownIndex;
|
||||
int _rightEyeDownIndex;
|
||||
int _leftEyeInIndex;
|
||||
int _rightEyeInIndex;
|
||||
int _leftEyeOpenIndex;
|
||||
int _rightEyeOpenIndex;
|
||||
|
||||
int _browDownLeftIndex;
|
||||
int _browDownRightIndex;
|
||||
|
|
|
@ -57,7 +57,7 @@ WebWindowClass::WebWindowClass(const QString& title, const QString& url, int wid
|
|||
} else {
|
||||
auto dialogWidget = new QDialog(Application::getInstance()->getWindow(), Qt::Window);
|
||||
dialogWidget->setWindowTitle(title);
|
||||
dialogWidget->setMinimumSize(width, height);
|
||||
dialogWidget->resize(width, height);
|
||||
connect(dialogWidget, &QDialog::finished, this, &WebWindowClass::hasClosed);
|
||||
|
||||
auto layout = new QVBoxLayout(dialogWidget);
|
||||
|
|
|
@ -495,7 +495,7 @@ void ApplicationCompositor::renderControllerPointers(gpu::Batch& batch) {
|
|||
glm::vec3 direction = glm::inverse(myAvatar->getOrientation()) * palmData->getFingerDirection();
|
||||
|
||||
// Get the angles, scaled between (-0.5,0.5)
|
||||
float xAngle = (atan2(direction.z, direction.x) + PI_OVER_TWO);
|
||||
float xAngle = (atan2f(direction.z, direction.x) + PI_OVER_TWO);
|
||||
float yAngle = 0.5f - ((atan2f(direction.z, direction.y) + (float)PI_OVER_TWO));
|
||||
|
||||
// Get the pixel range over which the xAngle and yAngle are scaled
|
||||
|
|
|
@ -125,8 +125,10 @@ void AudioStatsDialog::renderStats() {
|
|||
audioInputBufferLatency = (double)_stats->getAudioInputMsecsReadStats().getWindowAverage();
|
||||
inputRingBufferLatency = (double)_stats->getInputRungBufferMsecsAvailableStats().getWindowAverage();
|
||||
networkRoundtripLatency = (double) audioMixerNodePointer->getPingMs();
|
||||
mixerRingBufferLatency = (double)_stats->getMixerAvatarStreamStats()._framesAvailableAverage * AudioConstants::NETWORK_FRAME_MSECS;
|
||||
outputRingBufferLatency = (double)downstreamAudioStreamStats._framesAvailableAverage * AudioConstants::NETWORK_FRAME_MSECS;
|
||||
mixerRingBufferLatency = (double)_stats->getMixerAvatarStreamStats()._framesAvailableAverage *
|
||||
(double)AudioConstants::NETWORK_FRAME_MSECS;
|
||||
outputRingBufferLatency = (double)downstreamAudioStreamStats._framesAvailableAverage *
|
||||
(double)AudioConstants::NETWORK_FRAME_MSECS;
|
||||
audioOutputBufferLatency = (double)_stats->getAudioOutputMsecsUnplayedStats().getWindowAverage();
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,6 @@ void Cube3DOverlay::render(RenderArgs* args) {
|
|||
|
||||
// TODO: handle registration point??
|
||||
glm::vec3 position = getPosition();
|
||||
glm::vec3 center = getCenter();
|
||||
glm::vec3 dimensions = getDimensions();
|
||||
glm::quat rotation = getRotation();
|
||||
|
||||
|
|
|
@ -106,36 +106,6 @@ void Batch::drawIndexedInstanced(uint32 nbInstances, Primitive primitiveType, ui
|
|||
_params.push_back(nbInstances);
|
||||
}
|
||||
|
||||
void Batch::clearFramebuffer(Framebuffer::Masks targets, const Vec4& color, float depth, int stencil, bool enableScissor) {
|
||||
ADD_COMMAND(clearFramebuffer);
|
||||
|
||||
_params.push_back(enableScissor);
|
||||
_params.push_back(stencil);
|
||||
_params.push_back(depth);
|
||||
_params.push_back(color.w);
|
||||
_params.push_back(color.z);
|
||||
_params.push_back(color.y);
|
||||
_params.push_back(color.x);
|
||||
_params.push_back(targets);
|
||||
}
|
||||
|
||||
void Batch::clearColorFramebuffer(Framebuffer::Masks targets, const Vec4& color, bool enableScissor) {
|
||||
clearFramebuffer(targets & Framebuffer::BUFFER_COLORS, color, 1.0f, 0, enableScissor);
|
||||
}
|
||||
|
||||
void Batch::clearDepthFramebuffer(float depth, bool enableScissor) {
|
||||
clearFramebuffer(Framebuffer::BUFFER_DEPTH, Vec4(0.0f), depth, 0, enableScissor);
|
||||
}
|
||||
|
||||
void Batch::clearStencilFramebuffer(int stencil, bool enableScissor) {
|
||||
clearFramebuffer(Framebuffer::BUFFER_STENCIL, Vec4(0.0f), 1.0f, stencil, enableScissor);
|
||||
}
|
||||
|
||||
void Batch::clearDepthStencilFramebuffer(float depth, int stencil, bool enableScissor) {
|
||||
clearFramebuffer(Framebuffer::BUFFER_DEPTHSTENCIL, Vec4(0.0f), depth, stencil, enableScissor);
|
||||
}
|
||||
|
||||
|
||||
void Batch::setInputFormat(const Stream::FormatPointer& format) {
|
||||
ADD_COMMAND(setInputFormat);
|
||||
|
||||
|
@ -255,6 +225,35 @@ void Batch::setFramebuffer(const FramebufferPointer& framebuffer) {
|
|||
|
||||
}
|
||||
|
||||
void Batch::clearFramebuffer(Framebuffer::Masks targets, const Vec4& color, float depth, int stencil, bool enableScissor) {
|
||||
ADD_COMMAND(clearFramebuffer);
|
||||
|
||||
_params.push_back(enableScissor);
|
||||
_params.push_back(stencil);
|
||||
_params.push_back(depth);
|
||||
_params.push_back(color.w);
|
||||
_params.push_back(color.z);
|
||||
_params.push_back(color.y);
|
||||
_params.push_back(color.x);
|
||||
_params.push_back(targets);
|
||||
}
|
||||
|
||||
void Batch::clearColorFramebuffer(Framebuffer::Masks targets, const Vec4& color, bool enableScissor) {
|
||||
clearFramebuffer(targets & Framebuffer::BUFFER_COLORS, color, 1.0f, 0, enableScissor);
|
||||
}
|
||||
|
||||
void Batch::clearDepthFramebuffer(float depth, bool enableScissor) {
|
||||
clearFramebuffer(Framebuffer::BUFFER_DEPTH, Vec4(0.0f), depth, 0, enableScissor);
|
||||
}
|
||||
|
||||
void Batch::clearStencilFramebuffer(int stencil, bool enableScissor) {
|
||||
clearFramebuffer(Framebuffer::BUFFER_STENCIL, Vec4(0.0f), 1.0f, stencil, enableScissor);
|
||||
}
|
||||
|
||||
void Batch::clearDepthStencilFramebuffer(float depth, int stencil, bool enableScissor) {
|
||||
clearFramebuffer(Framebuffer::BUFFER_DEPTHSTENCIL, Vec4(0.0f), depth, stencil, enableScissor);
|
||||
}
|
||||
|
||||
void Batch::blit(const FramebufferPointer& src, const Vec4i& srcViewport,
|
||||
const FramebufferPointer& dst, const Vec4i& dstViewport) {
|
||||
ADD_COMMAND(blit);
|
||||
|
|
|
@ -54,15 +54,6 @@ public:
|
|||
void drawInstanced(uint32 nbInstances, Primitive primitiveType, uint32 nbVertices, uint32 startVertex = 0, uint32 startInstance = 0);
|
||||
void drawIndexedInstanced(uint32 nbInstances, Primitive primitiveType, uint32 nbIndices, uint32 startIndex = 0, uint32 startInstance = 0);
|
||||
|
||||
// Clear framebuffer layers
|
||||
// Targets can be any of the render buffers contained in the Framebuffer
|
||||
// Optionally the scissor test can be enabled locally for this command and to restrict the clearing command to the pixels contained in the scissor rectangle
|
||||
void clearFramebuffer(Framebuffer::Masks targets, const Vec4& color, float depth, int stencil, bool enableScissor = false);
|
||||
void clearColorFramebuffer(Framebuffer::Masks targets, const Vec4& color, bool enableScissor = false); // not a command, just a shortcut for clearFramebuffer, mask out targets to make sure it touches only color targets
|
||||
void clearDepthFramebuffer(float depth, bool enableScissor = false); // not a command, just a shortcut for clearFramebuffer, it touches only depth target
|
||||
void clearStencilFramebuffer(int stencil, bool enableScissor = false); // not a command, just a shortcut for clearFramebuffer, it touches only stencil target
|
||||
void clearDepthStencilFramebuffer(float depth, int stencil, bool enableScissor = false); // not a command, just a shortcut for clearFramebuffer, it touches depth and stencil target
|
||||
|
||||
// Input Stage
|
||||
// InputFormat
|
||||
// InputBuffers
|
||||
|
@ -105,8 +96,17 @@ public:
|
|||
|
||||
// Framebuffer Stage
|
||||
void setFramebuffer(const FramebufferPointer& framebuffer);
|
||||
void blit(const FramebufferPointer& src, const Vec4i& srcViewport,
|
||||
const FramebufferPointer& dst, const Vec4i& dstViewport);
|
||||
|
||||
// Clear framebuffer layers
|
||||
// Targets can be any of the render buffers contained in the currnetly bound Framebuffer
|
||||
// Optionally the scissor test can be enabled locally for this command and to restrict the clearing command to the pixels contained in the scissor rectangle
|
||||
void clearFramebuffer(Framebuffer::Masks targets, const Vec4& color, float depth, int stencil, bool enableScissor = false);
|
||||
void clearColorFramebuffer(Framebuffer::Masks targets, const Vec4& color, bool enableScissor = false); // not a command, just a shortcut for clearFramebuffer, mask out targets to make sure it touches only color targets
|
||||
void clearDepthFramebuffer(float depth, bool enableScissor = false); // not a command, just a shortcut for clearFramebuffer, it touches only depth target
|
||||
void clearStencilFramebuffer(int stencil, bool enableScissor = false); // not a command, just a shortcut for clearFramebuffer, it touches only stencil target
|
||||
void clearDepthStencilFramebuffer(float depth, int stencil, bool enableScissor = false); // not a command, just a shortcut for clearFramebuffer, it touches depth and stencil target
|
||||
|
||||
void blit(const FramebufferPointer& src, const Vec4i& srcViewport, const FramebufferPointer& dst, const Vec4i& dstViewport);
|
||||
|
||||
// Query Section
|
||||
void beginQuery(const QueryPointer& query);
|
||||
|
@ -162,8 +162,6 @@ public:
|
|||
COMMAND_drawInstanced,
|
||||
COMMAND_drawIndexedInstanced,
|
||||
|
||||
COMMAND_clearFramebuffer,
|
||||
|
||||
COMMAND_setInputFormat,
|
||||
COMMAND_setInputBuffer,
|
||||
COMMAND_setIndexBuffer,
|
||||
|
@ -181,6 +179,7 @@ public:
|
|||
COMMAND_setResourceTexture,
|
||||
|
||||
COMMAND_setFramebuffer,
|
||||
COMMAND_clearFramebuffer,
|
||||
COMMAND_blit,
|
||||
|
||||
COMMAND_beginQuery,
|
||||
|
|
|
@ -21,7 +21,6 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] =
|
|||
(&::gpu::GLBackend::do_drawIndexed),
|
||||
(&::gpu::GLBackend::do_drawInstanced),
|
||||
(&::gpu::GLBackend::do_drawIndexedInstanced),
|
||||
(&::gpu::GLBackend::do_clearFramebuffer),
|
||||
|
||||
(&::gpu::GLBackend::do_setInputFormat),
|
||||
(&::gpu::GLBackend::do_setInputBuffer),
|
||||
|
@ -40,6 +39,7 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] =
|
|||
(&::gpu::GLBackend::do_setResourceTexture),
|
||||
|
||||
(&::gpu::GLBackend::do_setFramebuffer),
|
||||
(&::gpu::GLBackend::do_clearFramebuffer),
|
||||
(&::gpu::GLBackend::do_blit),
|
||||
|
||||
(&::gpu::GLBackend::do_beginQuery),
|
||||
|
@ -246,71 +246,6 @@ void GLBackend::do_drawIndexedInstanced(Batch& batch, uint32 paramOffset) {
|
|||
(void) CHECK_GL_ERROR();
|
||||
}
|
||||
|
||||
void GLBackend::do_clearFramebuffer(Batch& batch, uint32 paramOffset) {
|
||||
|
||||
uint32 masks = batch._params[paramOffset + 7]._uint;
|
||||
Vec4 color;
|
||||
color.x = batch._params[paramOffset + 6]._float;
|
||||
color.y = batch._params[paramOffset + 5]._float;
|
||||
color.z = batch._params[paramOffset + 4]._float;
|
||||
color.w = batch._params[paramOffset + 3]._float;
|
||||
float depth = batch._params[paramOffset + 2]._float;
|
||||
int stencil = batch._params[paramOffset + 1]._int;
|
||||
int useScissor = batch._params[paramOffset + 0]._int;
|
||||
|
||||
GLuint glmask = 0;
|
||||
if (masks & Framebuffer::BUFFER_STENCIL) {
|
||||
glClearStencil(stencil);
|
||||
glmask |= GL_STENCIL_BUFFER_BIT;
|
||||
}
|
||||
|
||||
if (masks & Framebuffer::BUFFER_DEPTH) {
|
||||
glClearDepth(depth);
|
||||
glmask |= GL_DEPTH_BUFFER_BIT;
|
||||
}
|
||||
|
||||
std::vector<GLenum> drawBuffers;
|
||||
if (masks & Framebuffer::BUFFER_COLORS) {
|
||||
for (unsigned int i = 0; i < Framebuffer::MAX_NUM_RENDER_BUFFERS; i++) {
|
||||
if (masks & (1 << i)) {
|
||||
drawBuffers.push_back(GL_COLOR_ATTACHMENT0 + i);
|
||||
}
|
||||
}
|
||||
|
||||
if (!drawBuffers.empty()) {
|
||||
glDrawBuffers(drawBuffers.size(), drawBuffers.data());
|
||||
glClearColor(color.x, color.y, color.z, color.w);
|
||||
glmask |= GL_COLOR_BUFFER_BIT;
|
||||
}
|
||||
|
||||
// Force the color mask cache to WRITE_ALL if not the case
|
||||
do_setStateColorWriteMask(State::ColorMask::WRITE_ALL);
|
||||
}
|
||||
|
||||
// Apply scissor if needed and if not already on
|
||||
bool doEnableScissor = (useScissor && (!_pipeline._stateCache.scissorEnable));
|
||||
if (doEnableScissor) {
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
glClear(glmask);
|
||||
|
||||
// Restore scissor if needed
|
||||
if (doEnableScissor) {
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
// Restore the color draw buffers only if a frmaebuffer is bound
|
||||
if (_output._framebuffer && !drawBuffers.empty()) {
|
||||
auto glFramebuffer = syncGPUObject(*_output._framebuffer);
|
||||
if (glFramebuffer) {
|
||||
glDrawBuffers(glFramebuffer->_colorBuffers.size(), glFramebuffer->_colorBuffers.data());
|
||||
}
|
||||
}
|
||||
|
||||
(void) CHECK_GL_ERROR();
|
||||
}
|
||||
|
||||
// TODO: As long as we have gl calls explicitely issued from interface
|
||||
// code, we need to be able to record and batch these calls. THe long
|
||||
// term strategy is to get rid of any GL calls in favor of the HIFI GPU API
|
||||
|
|
|
@ -241,8 +241,6 @@ protected:
|
|||
void do_drawInstanced(Batch& batch, uint32 paramOffset);
|
||||
void do_drawIndexedInstanced(Batch& batch, uint32 paramOffset);
|
||||
|
||||
void do_clearFramebuffer(Batch& batch, uint32 paramOffset);
|
||||
|
||||
// Input Stage
|
||||
void do_setInputFormat(Batch& batch, uint32 paramOffset);
|
||||
void do_setInputBuffer(Batch& batch, uint32 paramOffset);
|
||||
|
@ -385,6 +383,7 @@ protected:
|
|||
|
||||
// Output stage
|
||||
void do_setFramebuffer(Batch& batch, uint32 paramOffset);
|
||||
void do_clearFramebuffer(Batch& batch, uint32 paramOffset);
|
||||
void do_blit(Batch& batch, uint32 paramOffset);
|
||||
|
||||
// Synchronize the state cache of this Backend with the actual real state of the GL Context
|
||||
|
|
|
@ -180,7 +180,6 @@ void GLBackend::syncOutputStateCache() {
|
|||
|
||||
void GLBackend::do_setFramebuffer(Batch& batch, uint32 paramOffset) {
|
||||
auto framebuffer = batch._framebuffers.get(batch._params[paramOffset]._uint);
|
||||
|
||||
if (_output._framebuffer != framebuffer) {
|
||||
auto newFBO = getFramebufferID(framebuffer);
|
||||
if (_output._drawFBO != newFBO) {
|
||||
|
@ -191,6 +190,72 @@ void GLBackend::do_setFramebuffer(Batch& batch, uint32 paramOffset) {
|
|||
}
|
||||
}
|
||||
|
||||
void GLBackend::do_clearFramebuffer(Batch& batch, uint32 paramOffset) {
|
||||
|
||||
uint32 masks = batch._params[paramOffset + 7]._uint;
|
||||
Vec4 color;
|
||||
color.x = batch._params[paramOffset + 6]._float;
|
||||
color.y = batch._params[paramOffset + 5]._float;
|
||||
color.z = batch._params[paramOffset + 4]._float;
|
||||
color.w = batch._params[paramOffset + 3]._float;
|
||||
float depth = batch._params[paramOffset + 2]._float;
|
||||
int stencil = batch._params[paramOffset + 1]._int;
|
||||
int useScissor = batch._params[paramOffset + 0]._int;
|
||||
|
||||
GLuint glmask = 0;
|
||||
if (masks & Framebuffer::BUFFER_STENCIL) {
|
||||
glClearStencil(stencil);
|
||||
glmask |= GL_STENCIL_BUFFER_BIT;
|
||||
}
|
||||
|
||||
if (masks & Framebuffer::BUFFER_DEPTH) {
|
||||
glClearDepth(depth);
|
||||
glmask |= GL_DEPTH_BUFFER_BIT;
|
||||
}
|
||||
|
||||
std::vector<GLenum> drawBuffers;
|
||||
if (masks & Framebuffer::BUFFER_COLORS) {
|
||||
for (unsigned int i = 0; i < Framebuffer::MAX_NUM_RENDER_BUFFERS; i++) {
|
||||
if (masks & (1 << i)) {
|
||||
drawBuffers.push_back(GL_COLOR_ATTACHMENT0 + i);
|
||||
}
|
||||
}
|
||||
|
||||
if (!drawBuffers.empty()) {
|
||||
glDrawBuffers(drawBuffers.size(), drawBuffers.data());
|
||||
glClearColor(color.x, color.y, color.z, color.w);
|
||||
glmask |= GL_COLOR_BUFFER_BIT;
|
||||
}
|
||||
|
||||
// Force the color mask cache to WRITE_ALL if not the case
|
||||
do_setStateColorWriteMask(State::ColorMask::WRITE_ALL);
|
||||
}
|
||||
|
||||
// Apply scissor if needed and if not already on
|
||||
bool doEnableScissor = (useScissor && (!_pipeline._stateCache.scissorEnable));
|
||||
if (doEnableScissor) {
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
// Clear!
|
||||
glClear(glmask);
|
||||
|
||||
// Restore scissor if needed
|
||||
if (doEnableScissor) {
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
// Restore the color draw buffers only if a frmaebuffer is bound
|
||||
if (_output._framebuffer && !drawBuffers.empty()) {
|
||||
auto glFramebuffer = syncGPUObject(*_output._framebuffer);
|
||||
if (glFramebuffer) {
|
||||
glDrawBuffers(glFramebuffer->_colorBuffers.size(), glFramebuffer->_colorBuffers.data());
|
||||
}
|
||||
}
|
||||
|
||||
(void) CHECK_GL_ERROR();
|
||||
}
|
||||
|
||||
void GLBackend::do_blit(Batch& batch, uint32 paramOffset) {
|
||||
auto srcframebuffer = batch._framebuffers.get(batch._params[paramOffset]._uint);
|
||||
Vec4i srcvp;
|
||||
|
@ -203,19 +268,31 @@ void GLBackend::do_blit(Batch& batch, uint32 paramOffset) {
|
|||
for (size_t i = 0; i < 4; ++i) {
|
||||
dstvp[i] = batch._params[paramOffset + 6 + i]._int;
|
||||
}
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, getFramebufferID(dstframebuffer));
|
||||
|
||||
// Assign dest framebuffer if not bound already
|
||||
auto newDrawFBO = getFramebufferID(dstframebuffer);
|
||||
if (_output._drawFBO != newDrawFBO) {
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, newDrawFBO);
|
||||
}
|
||||
|
||||
// always bind the read fbo
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, getFramebufferID(srcframebuffer));
|
||||
|
||||
// Blit!
|
||||
glBlitFramebuffer(srcvp.x, srcvp.y, srcvp.z, srcvp.w,
|
||||
dstvp.x, dstvp.y, dstvp.z, dstvp.w,
|
||||
GL_COLOR_BUFFER_BIT, GL_LINEAR);
|
||||
|
||||
(void) CHECK_GL_ERROR();
|
||||
|
||||
if (_output._framebuffer) {
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, getFramebufferID(_output._framebuffer));
|
||||
// Always clean the read fbo to 0
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
||||
|
||||
// Restore draw fbo if changed
|
||||
if (_output._drawFBO != newDrawFBO) {
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _output._drawFBO);
|
||||
}
|
||||
}
|
||||
|
||||
(void) CHECK_GL_ERROR();
|
||||
}
|
||||
|
||||
void GLBackend::downloadFramebuffer(const FramebufferPointer& srcFramebuffer, const Vec4i& region, QImage& destImage) {
|
||||
auto readFBO = gpu::GLBackend::getFramebufferID(srcFramebuffer);
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include "FboCache.h"
|
||||
#include <PerfStat.h>
|
||||
#include <NumericalConstants.h>
|
||||
|
||||
class QMyQuickRenderControl : public QQuickRenderControl {
|
||||
protected:
|
||||
|
@ -44,7 +45,10 @@ Q_LOGGING_CATEGORY(offscreenFocus, "hifi.offscreen.focus")
|
|||
// Time between receiving a request to render the offscreen UI actually triggering
|
||||
// the render. Could possibly be increased depending on the framerate we expect to
|
||||
// achieve.
|
||||
static const int SMALL_INTERVAL = 5;
|
||||
static const int MAX_QML_FRAMERATE = 10;
|
||||
static const int MIN_RENDER_INTERVAL_US = USECS_PER_SECOND / MAX_QML_FRAMERATE;
|
||||
static const int MIN_TIMER_MS = 5;
|
||||
|
||||
|
||||
OffscreenQmlSurface::OffscreenQmlSurface() :
|
||||
_renderControl(new QMyQuickRenderControl), _fboCache(new FboCache) {
|
||||
|
@ -90,7 +94,6 @@ void OffscreenQmlSurface::create(QOpenGLContext* shareContext) {
|
|||
// When Quick says there is a need to render, we will not render immediately. Instead,
|
||||
// a timer with a small interval is used to get better performance.
|
||||
_updateTimer.setSingleShot(true);
|
||||
_updateTimer.setInterval(SMALL_INTERVAL);
|
||||
connect(&_updateTimer, &QTimer::timeout, this, &OffscreenQmlSurface::updateQuick);
|
||||
|
||||
// Now hook up the signals. For simplicy we don't differentiate between
|
||||
|
@ -170,13 +173,18 @@ QObject* OffscreenQmlSurface::load(const QUrl& qmlSource, std::function<void(QQm
|
|||
|
||||
void OffscreenQmlSurface::requestUpdate() {
|
||||
_polish = true;
|
||||
if (!_updateTimer.isActive()) {
|
||||
_updateTimer.start();
|
||||
}
|
||||
requestRender();
|
||||
}
|
||||
|
||||
void OffscreenQmlSurface::requestRender() {
|
||||
if (!_updateTimer.isActive()) {
|
||||
auto now = usecTimestampNow();
|
||||
auto lastInterval = now - _lastRenderTime;
|
||||
if (lastInterval > MIN_RENDER_INTERVAL_US) {
|
||||
_updateTimer.setInterval(MIN_TIMER_MS);
|
||||
} else {
|
||||
_updateTimer.setInterval((MIN_RENDER_INTERVAL_US - lastInterval) / USECS_PER_MSEC);
|
||||
}
|
||||
_updateTimer.start();
|
||||
}
|
||||
}
|
||||
|
@ -243,6 +251,7 @@ void OffscreenQmlSurface::updateQuick() {
|
|||
if (_paused) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!makeCurrent()) {
|
||||
return;
|
||||
}
|
||||
|
@ -270,11 +279,11 @@ void OffscreenQmlSurface::updateQuick() {
|
|||
// Need a debug context with sync logging to figure out why.
|
||||
// for now just clear the errors
|
||||
glGetError();
|
||||
// Q_ASSERT(!glGetError());
|
||||
|
||||
_quickWindow->resetOpenGLState();
|
||||
|
||||
QOpenGLFramebufferObject::bindDefault();
|
||||
_lastRenderTime = usecTimestampNow();
|
||||
// Force completion of all the operations before we emit the texture as being ready for use
|
||||
glFinish();
|
||||
|
||||
|
|
|
@ -86,6 +86,7 @@ private:
|
|||
QQuickItem* _rootItem{ nullptr };
|
||||
QTimer _updateTimer;
|
||||
FboCache* _fboCache;
|
||||
quint64 _lastRenderTime{ 0 };
|
||||
bool _polish{ true };
|
||||
bool _paused{ true };
|
||||
MouseTranslator _mouseTranslator{ [](const QPointF& p) { return p; } };
|
||||
|
|
Loading…
Reference in a new issue