/*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <dali/internal/window-system/common/window-factory.h>
#include <dali/internal/window-system/common/window-system.h>
#include <dali/internal/graphics/gles/egl-graphics.h>
+#include <dali/internal/system/common/environment-variables.h>
namespace Dali
{
const int MINIMUM_DIMENSION_CHANGE( 1 ); ///< Minimum change for window to be considered to have moved
+const int TILE_SIZE = 16u; ///< Unit of tile size at GPU driver
#if defined(DEBUG_ENABLED)
Debug::Filter* gWindowRenderSurfaceLogFilter = Debug::Filter::New(Debug::Verbose, false, "LOG_WINDOW_RENDER_SURFACE");
} // unnamed namespace
WindowRenderSurface::WindowRenderSurface( Dali::PositionSize positionSize, Any surface, bool isTransparent )
-: mPositionSize( positionSize ),
+: mEGL( nullptr ),
+ mDisplayConnection( nullptr ),
+ mPositionSize( positionSize ),
mWindowBase(),
mThreadSynchronization( NULL ),
mRenderNotification( NULL ),
mOutputTransformedSignal(),
mRotationAngle( 0 ),
mScreenRotationAngle( 0 ),
+ mBufferAge( 0 ),
+ mPreBufferAge( 0 ),
mOwnSurface( false ),
mRotationSupported( false ),
mRotationFinished( true ),
mScreenRotationFinished( true ),
- mResizeFinished( true )
+ mResizeFinished( true ),
+ mDpiHorizontal( 0 ),
+ mDpiVertical( 0 ),
+ mPreDamagedRect()
{
DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "Creating Window\n" );
Initialize( surface );
{
delete mRotationTrigger;
}
+
+ if ( mEGLSurface )
+ {
+ DestroySurface();
+ }
}
void WindowRenderSurface::Initialize( Any surface )
if( mScreenRotationAngle != 0 )
{
mScreenRotationFinished = false;
+ mResizeFinished = false;
}
}
void WindowRenderSurface::RequestRotation( int angle, int width, int height )
{
- if( !mRotationSupported )
- {
- DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::Rotate: Rotation is not supported!\n" );
- return;
- }
-
if( !mRotationTrigger )
{
TriggerEventFactoryInterface& triggerFactory = Internal::Adaptor::Adaptor::GetImplementation( Adaptor::Get() ).GetTriggerEventFactoryInterface();
void WindowRenderSurface::GetDpi( unsigned int& dpiHorizontal, unsigned int& dpiVertical )
{
- mWindowBase->GetDpi( dpiHorizontal, dpiVertical );
+ if( mDpiHorizontal == 0 || mDpiVertical == 0 )
+ {
+ const char* environmentDpiHorizontal = std::getenv( DALI_ENV_DPI_HORIZONTAL );
+ mDpiHorizontal = environmentDpiHorizontal ? std::atoi( environmentDpiHorizontal ) : 0;
+
+ const char* environmentDpiVertical = std::getenv( DALI_ENV_DPI_VERTICAL );
+ mDpiVertical = environmentDpiVertical ? std::atoi( environmentDpiVertical ) : 0;
+
+ if( mDpiHorizontal == 0 || mDpiVertical == 0 )
+ {
+ mWindowBase->GetDpi( mDpiHorizontal, mDpiVertical );
+ }
+ }
+
+ dpiHorizontal = mDpiHorizontal;
+ dpiVertical = mDpiVertical;
+}
+
+int WindowRenderSurface::GetOrientation() const
+{
+ return mWindowBase->GetOrientation();
}
void WindowRenderSurface::InitializeGraphics()
// Check rotation capability
mRotationSupported = mWindowBase->IsEglWindowRotationSupported();
- DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::CreateSurface: w = %d h = %d angle = %d screen rotation = %d\n", mPositionSize.width, mPositionSize.height, mRotationAngle, mScreenRotationAngle );
+ DALI_LOG_RELEASE_INFO("WindowRenderSurface::CreateSurface: w = %d h = %d angle = %d screen rotation = %d\n",
+ mPositionSize.width, mPositionSize.height, mRotationAngle, mScreenRotationAngle );
}
void WindowRenderSurface::DestroySurface()
if( resizingSurface )
{
-#ifdef OVER_TIZEN_VERSION_4
+ int totalAngle = (mRotationAngle + mScreenRotationAngle) % 360;
+
// Window rotate or screen rotate
if( !mRotationFinished || !mScreenRotationFinished )
{
- int totalAngle = (mRotationAngle + mScreenRotationAngle) % 360;
-
mWindowBase->SetEglWindowRotation( totalAngle );
mWindowBase->SetEglWindowBufferTransform( totalAngle );
{
mWindowBase->SetEglWindowTransform( mRotationAngle );
}
-#endif
// Resize case
- if( !mResizeFinished )
+ if ( !mResizeFinished )
{
- mWindowBase->ResizeEglWindow( mPositionSize );
+ Dali::PositionSize positionSize;
+ positionSize.x = mPositionSize.x;
+ positionSize.y = mPositionSize.y;
+ if( totalAngle == 0 || totalAngle == 180 )
+ {
+ positionSize.width = mPositionSize.width;
+ positionSize.height = mPositionSize.height;
+ }
+ else
+ {
+ positionSize.width = mPositionSize.height;
+ positionSize.height = mPositionSize.width;
+ }
+
+ mWindowBase->ResizeEglWindow( positionSize );
mResizeFinished = true;
DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::PreRender: Set resize\n" );
return true;
}
+std::vector<int32_t> WindowRenderSurface::MergeRect( const Rect<int32_t>& damagedRect, int bufferAge )
+{
+ std::vector<int32_t> mergedRectArray;
+ // merge bounding
+ int dx1 = mPositionSize.width, dx2 = 0, dy1 = mPositionSize.height, dy2 = 0;
+ int checkWidth = mPositionSize.width - TILE_SIZE;
+ int checkHeight = mPositionSize.height - TILE_SIZE;
+
+ dx1 = std::min( damagedRect.x, dx1 );
+ dx2 = std::max( damagedRect.x + damagedRect.width, dx2);
+ dy1 = std::min( damagedRect.y, dy1 );
+ dy2 = std::max( damagedRect.y + damagedRect.height, dy2 );
+
+ for( int j = 0; j <= bufferAge; j++ )
+ {
+ if( !mPreDamagedRect[j].IsEmpty() )
+ {
+ dx1 = std::min( mPreDamagedRect[j].x, dx1 );
+ dx2 = std::max( mPreDamagedRect[j].x + mPreDamagedRect[j].width, dx2);
+ dy1 = std::min( mPreDamagedRect[j].y, dy1 );
+ dy2 = std::max( mPreDamagedRect[j].y + mPreDamagedRect[j].height, dy2 );
+
+ if( dx1 < TILE_SIZE && dx2 > checkWidth && dy1 < TILE_SIZE && dy2 > checkHeight )
+ {
+ dx1 = 0, dx2 = mPositionSize.width, dy1 = 0, dy2 = mPositionSize.height;
+ break;
+ }
+ }
+ }
+
+ dx1 = TILE_SIZE * (dx1 / TILE_SIZE);
+ dy1 = TILE_SIZE * (dy1 / TILE_SIZE);
+ dx2 = TILE_SIZE * ((dx2 + TILE_SIZE - 1) / TILE_SIZE);
+ dy2 = TILE_SIZE * ((dy2 + TILE_SIZE - 1) / TILE_SIZE);
+
+ mergedRectArray.push_back( dx1 );
+ mergedRectArray.push_back( dy1 );
+ mergedRectArray.push_back( dx2 - dx1 );
+ mergedRectArray.push_back( dy2 - dy1 );
+
+ return mergedRectArray;
+}
+
+
+void WindowRenderSurface::SetDamagedRect( const Dali::DamagedRect& damagedRect, Dali::DamagedRect& mergedRect )
+{
+ auto eglGraphics = static_cast<EglGraphics *>( mGraphics );
+ std::vector<int32_t> rectArray;
+ if( eglGraphics )
+ {
+ Internal::Adaptor::EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
+
+ rectArray = MergeRect( damagedRect, mBufferAge );
+
+ mPreDamagedRect[4] = std::move( mPreDamagedRect[3] );
+ mPreDamagedRect[3] = std::move( mPreDamagedRect[2] );
+ mPreDamagedRect[2] = std::move( mPreDamagedRect[1] );
+ mPreDamagedRect[1] = std::move( mPreDamagedRect[0] );
+ mPreDamagedRect[0] = std::move( damagedRect );
+
+ eglImpl.SetDamagedRect( rectArray, mEGLSurface );
+ }
+
+ if( !rectArray.empty() )
+ {
+ mergedRect.x = rectArray[0];
+ mergedRect.y = rectArray[1];
+ mergedRect.width = rectArray[2];
+ mergedRect.height = rectArray[3];
+ }
+}
+
+int32_t WindowRenderSurface::GetBufferAge()
+{
+ int result = mBufferAge = 0;
+ auto eglGraphics = static_cast<EglGraphics *>( mGraphics );
+ if( eglGraphics )
+ {
+ Internal::Adaptor::EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
+ mBufferAge = eglImpl.GetBufferAge( mEGLSurface );;
+ result = ( mBufferAge != mPreBufferAge ) ? 0 : mBufferAge;
+ mPreBufferAge = mBufferAge;
+ }
+ return result;
+}
+
void WindowRenderSurface::PostRender( bool renderToFbo, bool replacingSurface, bool resizingSurface )
{
// Inform the gl implementation that rendering has finished before informing the surface
}
Internal::Adaptor::EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
+
eglImpl.SwapBuffers( mEGLSurface );
if( mRenderNotification )
{
mScreenRotationAngle = screenRotationAngle;
mScreenRotationFinished = false;
+ mResizeFinished = false;
mOutputTransformedSignal.Emit();