Skip to content

Commit

Permalink
Support screen rotations for Tizen 4.0 and Tizen 6.0 (#28)
Browse files Browse the repository at this point in the history
* Support screen rotations for tizen4.0 and tizen6.0

Screen rotations sequence:
1.Register ecore rotate event callback.
2.Set rotate for ecore window when receive rotate event.
3.Resize ecore window.
4.Resize egl window.
5.Reize flutter UI.
6.Send rotate done before swap buffer.

* Refactor screen rotations according to code reviews suggestions

1.Remove GetWindowData func.
2.Remove struct WindowData.

* Add newline at end of file
  • Loading branch information
xiaowei-guan authored Jan 28, 2021
1 parent ac00eef commit 02a7411
Show file tree
Hide file tree
Showing 11 changed files with 148 additions and 51 deletions.
4 changes: 2 additions & 2 deletions shell/platform/tizen/channels/text_input_channel.cc
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ void TextInputChannel::InputPanelStateChangedCallback(
case ECORE_IMF_INPUT_PANEL_STATE_SHOW: {
FT_LOGD("[PANEL_STATE_SHOW]\n");
if (self->engine_->device_profile ==
"mobile") { // FIXME : Needs improvement on other devices.
"mobileD") { // FIXME : Needs improvement on other devices.
ecore_timer_add(
0.25,
[](void* data) -> Eina_Bool {
Expand Down Expand Up @@ -611,7 +611,7 @@ void TextInputChannel::HideSoftwareKeyboard() {
is_software_keyboard_showing_ = false;

if (engine_->device_profile ==
"mobile") { // FIXME : Needs improvement on other devices.
"mobileD") { // FIXME : Needs improvement on other devices.
auto window_geometry = engine_->tizen_renderer->GetGeometry();

if (rotation == 90 || rotation == 270) {
Expand Down
3 changes: 0 additions & 3 deletions shell/platform/tizen/flutter_tizen.cc
Original file line number Diff line number Diff line change
Expand Up @@ -221,9 +221,6 @@ void FlutterNotifyLowMemoryWarning(FlutterWindowControllerRef controller) {

void FlutterRotateWindow(FlutterWindowControllerRef controller,
int32_t degree) {
if (controller->engine) {
controller->engine->SetWindowOrientation(degree);
}
}

int64_t FlutterRegisterExternalTexture(
Expand Down
18 changes: 11 additions & 7 deletions shell/platform/tizen/tizen_embedder_engine.cc
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ TizenEmbedderEngine::TizenEmbedderEngine(
: device_profile(GetDeviceProfile()), device_dpi(GetDeviceDpi()) {
#ifdef FLUTTER_TIZEN_4
tizen_renderer = std::make_unique<TizenRendererEcoreWl>(
window_properties.x, window_properties.y, window_properties.width,
*this, window_properties.x, window_properties.y, window_properties.width,
window_properties.height);
#else
tizen_renderer = std::make_unique<TizenRendererEcoreWl2>(
window_properties.x, window_properties.y, window_properties.width,
*this, window_properties.x, window_properties.y, window_properties.width,
window_properties.height);
#endif

Expand Down Expand Up @@ -198,10 +198,13 @@ bool TizenEmbedderEngine::RunEngine(
touch_event_handler_ = std::make_unique<TouchEventHandler>(this);

SetWindowOrientation(0);

return true;
}

void TizenEmbedderEngine::OnRotationChange(int angle) {
SetWindowOrientation(angle);
}

bool TizenEmbedderEngine::StopEngine() {
if (flutter_engine) {
if (platform_view_channel) {
Expand Down Expand Up @@ -270,16 +273,13 @@ void TizenEmbedderEngine::SetWindowOrientation(int32_t degree) {
return;
}

tizen_renderer->SetRotate(degree);
// Compute renderer transformation based on the angle of rotation.
double rad = (360 - degree) * M_PI / 180;
auto geometry = tizen_renderer->GetGeometry();
double width = geometry.w;
double height = geometry.h;

if (text_input_channel->IsSoftwareKeyboardShowing()) {
height -= text_input_channel->GetCurrentKeyboardGeometry().h;
}

double trans_x = 0.0, trans_y = 0.0;
if (degree == 90) {
trans_y = height;
Expand All @@ -297,8 +297,12 @@ void TizenEmbedderEngine::SetWindowOrientation(int32_t degree) {
touch_event_handler_->rotation = degree;
text_input_channel->rotation = degree;
if (degree == 90 || degree == 270) {
tizen_renderer->ResizeWithRotation(geometry.x, geometry.y, height, width,
degree);
SendWindowMetrics(height, width, 0.0);
} else {
tizen_renderer->ResizeWithRotation(geometry.x, geometry.y, width, height,
degree);
SendWindowMetrics(width, height, 0.0);
}
}
Expand Down
3 changes: 2 additions & 1 deletion shell/platform/tizen/tizen_embedder_engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ struct FlutterTextureRegistrar {
using UniqueAotDataPtr = std::unique_ptr<_FlutterEngineAOTData, AOTDataDeleter>;

// Manages state associated with the underlying FlutterEngine.
class TizenEmbedderEngine {
class TizenEmbedderEngine : public TizenRenderer::Delegate {
public:
explicit TizenEmbedderEngine(
const FlutterWindowProperties& window_properties);
Expand All @@ -87,6 +87,7 @@ class TizenEmbedderEngine {
void AppIsResumed();
void AppIsPaused();
void AppIsDetached();
void OnRotationChange(int degree) override;

// The Flutter engine instance.
FLUTTER_API_SYMBOL(FlutterEngine) flutter_engine;
Expand Down
10 changes: 10 additions & 0 deletions shell/platform/tizen/tizen_renderer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@

#include "flutter/shell/platform/tizen/tizen_log.h"

TizenRenderer::TizenRenderer(TizenRenderer::Delegate& delegate)
: delegate_(delegate) {}

TizenRenderer::~TizenRenderer() = default;

bool TizenRenderer::OnMakeCurrent() {
Expand Down Expand Up @@ -58,6 +61,12 @@ bool TizenRenderer::OnPresent() {
FT_LOGE("Invalid TizenRenderer");
return false;
}

if(received_rotation) {
SendRotationChangeDone();
received_rotation = false;
}

if (eglSwapBuffers(egl_display_, egl_surface_) != EGL_TRUE) {
FT_LOGE("Could not swap EGl buffer");
PrintEGLError();
Expand Down Expand Up @@ -217,6 +226,7 @@ bool TizenRenderer::InitializeRenderer(int32_t x, int32_t y, int32_t w,
FT_LOGE("setupEglSurface fail");
return false;
}
Show();
is_valid_ = true;
return true;
}
Expand Down
18 changes: 14 additions & 4 deletions shell/platform/tizen/tizen_renderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,13 @@ class TizenRenderer {
struct TizenWindowGeometry {
int32_t x{0}, y{0}, w{0}, h{0};
};
TizenRenderer() = default;

class Delegate {
public:
virtual void OnRotationChange(int angle) = 0;
};

TizenRenderer(TizenRenderer::Delegate& deleget);
virtual ~TizenRenderer();
bool OnMakeCurrent();
bool OnClearCurrent();
Expand All @@ -22,11 +28,15 @@ class TizenRenderer {
void* OnProcResolver(const char* name);
virtual TizenWindowGeometry GetGeometry() = 0;
bool IsValid();
virtual void Show() = 0;
virtual void SetRotate(int angle) = 0;
virtual int GetEcoreWindowId() = 0;
virtual void ResizeWithRotation(int32_t dx, int32_t dy, int32_t width,
virtual void ResizeWithRotation(int32_t x, int32_t y, int32_t width,
int32_t height, int32_t degree) = 0;

protected:
bool received_rotation{false};
TizenRenderer::Delegate& delegate_;
bool InitializeRenderer(int32_t x, int32_t y, int32_t w, int32_t h);
virtual bool SetupDisplay() = 0;
virtual bool SetupEcoreWlWindow(int32_t x, int32_t y, int32_t w,
Expand All @@ -35,12 +45,12 @@ class TizenRenderer {
bool SetupEglSurface();
virtual EGLDisplay GetEGLDisplay() = 0;
virtual EGLNativeWindowType GetEGLNativeWindowType() = 0;

void DestoryRenderer();
void DestoryEglSurface();
virtual void DestoryEglWindow() = 0;
virtual void DestoryEcoreWlWindow() = 0;
virtual void ShutdownDisplay() = 0;
virtual void SendRotationChangeDone() = 0;

private:
bool is_valid_ = false;
Expand All @@ -53,4 +63,4 @@ class TizenRenderer {
bool ChooseEGLConfiguration();
void PrintEGLError();
};
#endif
#endif //EMBEDDER_TIZEN_RENDERER_H
62 changes: 47 additions & 15 deletions shell/platform/tizen/tizen_renderer_ecore_wl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@

#include "flutter/shell/platform/tizen/tizen_log.h"

TizenRendererEcoreWl::TizenRendererEcoreWl(int32_t x, int32_t y, int32_t w,
int32_t h) {
TizenRendererEcoreWl::TizenRendererEcoreWl(TizenRenderer::Delegate &delegate,
int32_t x, int32_t y, int32_t w,
int32_t h)
: TizenRenderer(delegate) {
InitializeRenderer(x, y, w, h);
}

TizenRendererEcoreWl::~TizenRendererEcoreWl() { DestoryRenderer(); }

bool TizenRendererEcoreWl::SetupDisplay() {
Expand All @@ -25,12 +28,14 @@ bool TizenRendererEcoreWl::SetupDisplay() {
}
return true;
}

bool TizenRendererEcoreWl::SetupEcoreWlWindow(int32_t x, int32_t y, int32_t w,
int32_t h) {
if (w == 0 || h == 0) {
FT_LOGE("Failed to create because of the wrong size");
return false;
}

ecore_wl_window_ = ecore_wl_window_new(
nullptr, x, y, w, h, ECORE_WL_WINDOW_BUFFER_TYPE_EGL_WINDOW);
FT_LOGD("ecore_wl_window_: %p", ecore_wl_window_);
Expand All @@ -43,8 +48,44 @@ bool TizenRendererEcoreWl::SetupEcoreWlWindow(int32_t x, int32_t y, int32_t w,
ecore_wl_window_aux_hint_add(ecore_wl_window_, 0,
"wm.policy.win.user.geometry", "1");
ecore_wl_window_show(ecore_wl_window_);
int rotations[4] = {0, 90, 180, 270};
ecore_wl_window_rotation_available_rotations_set(
ecore_wl_window_, rotations, sizeof(rotations) / sizeof(int));
ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_ROTATE, RotationEventCb, this);
return true;
}

Eina_Bool TizenRendererEcoreWl::RotationEventCb(void *data, int type,
void *event) {
auto *self = reinterpret_cast<TizenRendererEcoreWl *>(data);
Ecore_Wl_Event_Window_Rotate *ev =
reinterpret_cast<Ecore_Wl_Event_Window_Rotate *>(event);
self->delegate_.OnRotationChange(ev->angle);
return ECORE_CALLBACK_PASS_ON;
}

void TizenRendererEcoreWl::Show() { ecore_wl_window_show(ecore_wl_window_); }
void TizenRendererEcoreWl::SetRotate(int degree) {
ecore_wl_window_rotation_set(ecore_wl_window_, degree);
received_rotation = true;
}

void TizenRendererEcoreWl::ResizeWithRotation(int32_t x, int32_t y,
int32_t width, int32_t height,
int32_t degree) {
wl_egl_window_set_buffer_transform(wl_egl_window_, degree / 90);
wl_egl_window_set_window_transform(wl_egl_window_, degree / 90);

if ((degree == 90) || (degree == 270))
wl_egl_window_resize(wl_egl_window_, height, width, x, y);
else
wl_egl_window_resize(wl_egl_window_, width, height, x, y);
}

void TizenRendererEcoreWl::SendRotationChangeDone() {
ecore_wl_window_rotation_change_done_send(ecore_wl_window_);
}

bool TizenRendererEcoreWl::SetupEglWindow(int32_t w, int32_t h) {
wl_egl_window_ =
wl_egl_window_create(ecore_wl_window_surface_get(ecore_wl_window_), w, h);
Expand All @@ -54,9 +95,11 @@ bool TizenRendererEcoreWl::SetupEglWindow(int32_t w, int32_t h) {
}
return true;
}

EGLDisplay TizenRendererEcoreWl::GetEGLDisplay() {
return eglGetDisplay((EGLNativeDisplayType)wl_display_);
}

EGLNativeWindowType TizenRendererEcoreWl::GetEGLNativeWindowType() {
return (EGLNativeWindowType)wl_egl_window_;
}
Expand All @@ -67,12 +110,14 @@ void TizenRendererEcoreWl::DestoryEglWindow() {
wl_egl_window_ = nullptr;
}
}

void TizenRendererEcoreWl::DestoryEcoreWlWindow() {
if (ecore_wl_window_) {
ecore_wl_window_free(ecore_wl_window_);
ecore_wl_window_ = nullptr;
}
}

void TizenRendererEcoreWl::ShutdownDisplay() { ecore_wl_shutdown(); }

TizenRenderer::TizenWindowGeometry TizenRendererEcoreWl::GetGeometry() {
Expand All @@ -82,19 +127,6 @@ TizenRenderer::TizenWindowGeometry TizenRendererEcoreWl::GetGeometry() {
return result;
}

void TizenRendererEcoreWl::ResizeWithRotation(int32_t dx, int32_t dy,
int32_t width, int32_t height,
int32_t degree) {
wl_egl_window_resize(wl_egl_window_, width, height, dx, dy);
wl_egl_window_rotation rotations[4] = {ROTATION_0, ROTATION_90, ROTATION_180,
ROTATION_270};
int index = 0;
if (degree > 0) {
index = (degree / 90) % 4;
}
wl_egl_window_set_rotation(wl_egl_window_, rotations[index]);
}

int TizenRendererEcoreWl::GetEcoreWindowId() {
return ecore_wl_window_id_get(ecore_wl_window_);
}
13 changes: 9 additions & 4 deletions shell/platform/tizen/tizen_renderer_ecore_wl.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,15 @@
#include <Ecore_Wayland.h>
class TizenRendererEcoreWl : public TizenRenderer {
public:
TizenRendererEcoreWl(int32_t x, int32_t y, int32_t w, int32_t h);
TizenRendererEcoreWl(TizenRenderer::Delegate& delegate, int32_t x, int32_t y,
int32_t w, int32_t h);
~TizenRendererEcoreWl();
TizenRenderer::TizenWindowGeometry GetGeometry() override;
int GetEcoreWindowId() override;
void ResizeWithRotation(int32_t dx, int32_t dy, int32_t width, int32_t height,
void Show() override;
void SetRotate(int angle) override;
void ResizeWithRotation(int32_t x, int32_t y, int32_t width, int32_t height,
int32_t degree) override;
int GetEcoreWindowId() override;

protected:
void DestoryEglWindow() override;
Expand All @@ -29,10 +32,12 @@ class TizenRendererEcoreWl : public TizenRenderer {
bool SetupEcoreWlWindow(int32_t x, int32_t y, int32_t w, int32_t h) override;
bool SetupEglWindow(int32_t w, int32_t h) override;
void ShutdownDisplay() override;
void SendRotationChangeDone() override;

private:
Ecore_Wl_Window* ecore_wl_window_ = nullptr;
wl_egl_window* wl_egl_window_ = nullptr;
wl_display* wl_display_ = nullptr;
static Eina_Bool RotationEventCb(void* data, int type, void* event);
};
#endif
#endif //EMBEDDER_TIZEN_RENDERER_ECORE_WL_H
Loading

0 comments on commit 02a7411

Please sign in to comment.