mIsKhrCreateContextSupported( false ),
mSwapBufferCountAfterResume( 0 ),
mEglSetDamageRegionKHR( 0 ),
- mEglSwapBuffersWithDamageKHR( 0 ),
- mBufferAge( 0 ),
- mFullSwapNextFrame( true )
+ mEglSwapBuffersWithDamageKHR( 0 )
{
}
// DALI_LOG_ERROR("EglImplementation::SwapBuffers()\n");
eglSwapBuffers( mEglDisplay, eglSurface );
- mFullSwapNextFrame = false;
#ifndef DALI_PROFILE_UBUNTU
if( mSwapBufferCountAfterResume < THRESHOLD_SWAPBUFFER_COUNT )
return age;
}
-bool EglImplementation::DamageAreasSet() const
+void EglImplementation::SetDamageRegion( EGLSurface& eglSurface, std::vector< Rect< int > >& damagedRects )
{
- return (mDamagedAreas.size() ? true : false);
-}
-
-void EglImplementation::SetDamageAreas( std::vector<Dali::Rect<int>>& damagedAreas )
-{
- mFullSwapNextFrame = true;
- mDamagedAreas = damagedAreas;
-}
-
-void EglImplementation::SetFullSwapNextFrame()
-{
- mFullSwapNextFrame = true;
-}
-
-void mergeRects(Rect<int>& mergingRect, const std::vector<Rect<int>>& rects)
-{
- uint32_t i = 0;
- if (mergingRect.IsEmpty())
- {
- for (;i < rects.size(); i++)
- {
- if (!rects[i].IsEmpty())
- {
- mergingRect = rects[i];
- break;
- }
- }
- }
-
- for (;i < rects.size(); i++)
- {
- mergingRect.Merge(rects[i]);
- }
-}
-
-void insertRects(std::list<std::vector<Rect<int>>>& damagedRectsList, const std::vector<Rect<int>>& damagedRects)
-{
- damagedRectsList.push_front(damagedRects);
- if (damagedRectsList.size() > 4) // past triple buffers + current
- {
- damagedRectsList.pop_back();
- }
-}
-
-void EglImplementation::SetDamage( EGLSurface& eglSurface, const std::vector<Rect<int>>& damagedRects, Rect<int>& clippingRect )
-{
- if (!mPartialUpdateRequired)
+ if( !mPartialUpdateRequired )
{
return;
}
- if (eglSurface != EGL_NO_SURFACE) // skip if using surfaceless context
+ if( eglSurface != EGL_NO_SURFACE ) // skip if using surfaceless context
{
- EGLint width = 0;
- EGLint height = 0;
- eglQuerySurface(mEglDisplay, eglSurface, EGL_WIDTH, &width);
- eglQuerySurface(mEglDisplay, eglSurface, EGL_HEIGHT, &height);
- Rect<int> surfaceRect(0, 0, width, height);
-
- mSurfaceRect = surfaceRect;
-
- if (mFullSwapNextFrame)
- {
- mBufferAge = 0;
- insertRects(mBufferDamagedRects, std::vector<Rect<int>>(1, surfaceRect));
- clippingRect = Rect<int>();
- return;
- }
-
- EGLint bufferAge = GetBufferAge(eglSurface);
- if (mDamagedAreas.size())
- {
- mBufferAge = bufferAge;
- if (bufferAge == 0)
- {
- // Buffer age is reset
- clippingRect = Rect<int>();
- return;
- }
-
- mergeRects(clippingRect, mDamagedAreas);
- }
- else
- {
- // Buffer age 0 means the back buffer in invalid and requires full swap
- if (!damagedRects.size() || bufferAge != mBufferAge || bufferAge == 0)
- {
- // No damage or buffer is out of order or buffer age is reset
- mBufferAge = bufferAge;
- insertRects(mBufferDamagedRects, std::vector<Rect<int>>(1, surfaceRect));
- clippingRect = Rect<int>();
- return;
- }
-
- // We push current frame damaged rects here, zero index for current frame
- mBufferAge = bufferAge;
- insertRects(mBufferDamagedRects, damagedRects);
-
- // Merge damaged rects into clipping rect
- auto bufferDamagedRects = mBufferDamagedRects.begin();
- while (bufferAge-- >= 0 && bufferDamagedRects != mBufferDamagedRects.end())
- {
- const std::vector<Rect<int>>& rects = *bufferDamagedRects++;
- mergeRects(clippingRect, rects);
- }
- }
-
- if (!clippingRect.Intersect(surfaceRect) || clippingRect.Area() > surfaceRect.Area() * 0.8)
- {
- // clipping area too big or doesn't intersect surface rect
- clippingRect = Rect<int>();
- return;
- }
-
- // DALI_LOG_ERROR("eglSetDamageRegionKHR(%d, %d, %d, %d)\n", clippingRect.x, clippingRect.y, clippingRect.width, clippingRect.height);
- EGLBoolean result = mEglSetDamageRegionKHR(mEglDisplay, eglSurface, reinterpret_cast<int*>(&clippingRect), 1);
+ EGLBoolean result = mEglSetDamageRegionKHR( mEglDisplay, eglSurface, reinterpret_cast< int* >( damagedRects.data() ), 1 );
if (result == EGL_FALSE)
{
- DALI_LOG_ERROR("eglSetDamageRegionKHR(%d)\n", eglGetError());
+ DALI_LOG_ERROR( "eglSetDamageRegionKHR(%d)\n", eglGetError() );
}
}
}
{
if (eglSurface != EGL_NO_SURFACE ) // skip if using surfaceless context
{
- if (!mPartialUpdateRequired || mFullSwapNextFrame || mBufferAge == 0 || !damagedRects.size())
+ if (!mPartialUpdateRequired )
{
SwapBuffers(eglSurface);
return;
}
#endif //DALI_PROFILE_UBUNTU
- if (mDamagedAreas.size())
- {
- // DALI_LOG_ERROR("EglImplementation::SwapBuffers(%d)\n", mDamagedAreas.size());
- EGLBoolean result = mEglSwapBuffersWithDamageKHR(mEglDisplay, eglSurface, reinterpret_cast<int*>(mDamagedAreas.data()), mDamagedAreas.size());
- if (result == EGL_FALSE)
- {
- DALI_LOG_ERROR("eglSwapBuffersWithDamageKHR(%d)\n", eglGetError());
- }
-
-#ifndef DALI_PROFILE_UBUNTU
- if( mSwapBufferCountAfterResume < THRESHOLD_SWAPBUFFER_COUNT )
- {
- DALI_LOG_RELEASE_INFO( "EglImplementation::SwapBuffers finished.\n" );
- mSwapBufferCountAfterResume++;
- }
-#endif //DALI_PROFILE_UBUNTU
- return;
- }
-
- // current frame damaged rects were pushed by EglImplementation::SetDamage() to 0 index.
- EGLint bufferAge = mBufferAge;
- mCombinedDamagedRects.clear();
-
- // Combine damaged rects from previous frames (beginning from bufferAge index) with the current frame (0 index)
- auto bufferDamagedRects = mBufferDamagedRects.begin();
- while (bufferAge-- >= 0 && bufferDamagedRects != mBufferDamagedRects.end())
- {
- const std::vector<Rect<int>>& rects = *bufferDamagedRects++;
- mCombinedDamagedRects.insert(mCombinedDamagedRects.end(), rects.begin(), rects.end());
- }
-
- // Merge intersecting rects, form an array of non intersecting rects to help driver a bit
- // Could be optional and can be removed, needs to be checked with and without on platform
- const int n = mCombinedDamagedRects.size();
- for (int i = 0; i < n-1; i++)
- {
- if (mCombinedDamagedRects[i].IsEmpty())
- {
- continue;
- }
-
- for (int j = i+1; j < n; j++)
- {
- if (mCombinedDamagedRects[j].IsEmpty())
- {
- continue;
- }
-
- if (mCombinedDamagedRects[i].Intersects(mCombinedDamagedRects[j]))
- {
- mCombinedDamagedRects[i].Merge(mCombinedDamagedRects[j]);
- mCombinedDamagedRects[j].width = 0;
- mCombinedDamagedRects[j].height = 0;
- }
- }
- }
-
- int j = 0;
- for (int i = 0; i < n; i++)
- {
- if (!mCombinedDamagedRects[i].IsEmpty())
- {
- mCombinedDamagedRects[j++] = mCombinedDamagedRects[i];
- }
- }
-
- if (j != 0)
- {
- mCombinedDamagedRects.resize(j);
- }
-
- if (!mCombinedDamagedRects.size() || (mCombinedDamagedRects[0].Area() > mSurfaceRect.Area() * 0.8))
- {
- SwapBuffers(eglSurface);
- return;
- }
-
- // DALI_LOG_ERROR("EglImplementation::SwapBuffers(%d)\n", mCombinedDamagedRects.size());
- EGLBoolean result = mEglSwapBuffersWithDamageKHR(mEglDisplay, eglSurface, reinterpret_cast<int*>(mCombinedDamagedRects.data()), mCombinedDamagedRects.size());
+ EGLBoolean result = mEglSwapBuffersWithDamageKHR(mEglDisplay, eglSurface, reinterpret_cast<int*>(const_cast< std::vector< Rect< int > >& >( damagedRects ).data()), damagedRects.size());
if (result == EGL_FALSE)
{
DALI_LOG_ERROR("eglSwapBuffersWithDamageKHR(%d)\n", eglGetError());
}
}
+bool EglImplementation::IsPartialUpdateRequired() const
+{
+ return mPartialUpdateRequired;
+}
+
} // namespace Adaptor
} // namespace Internal