+ }
+}
+
+void WindowRenderSurface::SetBufferDamagedRects( const std::vector< Rect< int > >& damagedRects, Rect< int >& clippingRect )
+{
+ auto eglGraphics = static_cast< EglGraphics* >( mGraphics );
+ if ( eglGraphics )
+ {
+ Internal::Adaptor::EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
+ if( !eglImpl.IsPartialUpdateRequired() )
+ {
+ return;
+ }
+
+ Rect< int > surfaceRect( 0, 0, mPositionSize.width, mPositionSize.height );
+
+ if( mFullSwapNextFrame )
+ {
+ InsertRects( mBufferDamagedRects, std::vector< Rect< int > >( 1, surfaceRect ) );
+ clippingRect = Rect< int >();
+ return;
+ }
+
+ EGLint bufferAge = eglImpl.GetBufferAge( mEGLSurface );
+
+ // Buffer age 0 means the back buffer in invalid and requires full swap
+ if( !damagedRects.size() || bufferAge == 0 )
+ {
+ InsertRects( mBufferDamagedRects, std::vector< Rect< int > >( 1, surfaceRect ) );
+ clippingRect = Rect< int >();
+ return;
+ }
+
+ // We push current frame damaged rects here, zero index for current frame
+ 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() * FULL_UPDATE_RATIO )
+ {
+ // clipping area too big or doesn't intersect surface rect
+ clippingRect = Rect< int >();
+ return;
+ }
+
+ std::vector< Rect< int > > damagedRegion;
+ damagedRegion.push_back( clippingRect );
+
+ eglImpl.SetDamageRegion( mEGLSurface, damagedRegion );
+ }
+}
+
+void WindowRenderSurface::SwapBuffers( const std::vector<Rect<int>>& damagedRects )
+{
+ auto eglGraphics = static_cast< EglGraphics* >( mGraphics );
+ if( eglGraphics )
+ {
+ Rect< int > surfaceRect( 0, 0, mPositionSize.width, mPositionSize.height );
+
+ Internal::Adaptor::EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
+
+ if( !eglImpl.IsPartialUpdateRequired() || mFullSwapNextFrame || !damagedRects.size() || (damagedRects[0].Area() > surfaceRect.Area() * FULL_UPDATE_RATIO) )
+ {
+ mFullSwapNextFrame = false;
+ eglImpl.SwapBuffers( mEGLSurface );
+ return;
+ }
+
+ mFullSwapNextFrame = false;
+
+ std::vector< Rect< int > > mergedRects = damagedRects;
+
+ // 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 = mergedRects.size();
+ for( int i = 0; i < n - 1; i++ )
+ {
+ if( mergedRects[i].IsEmpty() )
+ {
+ continue;
+ }
+
+ for( int j = i + 1; j < n; j++ )
+ {
+ if( mergedRects[j].IsEmpty() )
+ {
+ continue;
+ }
+
+ if( mergedRects[i].Intersects( mergedRects[j] ) )
+ {
+ mergedRects[i].Merge( mergedRects[j] );
+ mergedRects[j].width = 0;
+ mergedRects[j].height = 0;
+ }
+ }
+ }
+
+ int j = 0;
+ for( int i = 0; i < n; i++ )
+ {
+ if( !mergedRects[i].IsEmpty() )
+ {
+ mergedRects[j++] = mergedRects[i];
+ }
+ }
+
+ if( j != 0 )
+ {
+ mergedRects.resize( j );
+ }
+
+ if( !mergedRects.size() || ( mergedRects[0].Area() > surfaceRect.Area() * FULL_UPDATE_RATIO ) )
+ {
+ eglImpl.SwapBuffers( mEGLSurface );
+ }
+ else
+ {
+ eglImpl.SwapBuffers( mEGLSurface, mergedRects );
+ }