Skip to content

Commit

Permalink
Add screen rotation API (flutter-tizen#26)
Browse files Browse the repository at this point in the history
  • Loading branch information
swift-kim authored and GitHub Enterprise committed Oct 27, 2020
1 parent d602ea0 commit f63b250
Show file tree
Hide file tree
Showing 8 changed files with 117 additions and 89 deletions.
47 changes: 21 additions & 26 deletions shell/platform/tizen/flutter_tizen.cc
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ FlutterWindowControllerRef FlutterCreateWindow(
auto state = std::make_unique<FlutterWindowControllerState>();
state->engine = std::make_unique<TizenEmbedderEngine>();

if (!state->engine->EmbedderCreateWindow(window_properties)) {
if (!state->engine->CreateWindow(window_properties)) {
LoggerE("Failed to create window");
return nullptr;
}
Expand All @@ -101,7 +101,7 @@ FlutterWindowControllerRef FlutterCreateWindow(

void FlutterDestoryWindow(FlutterWindowControllerRef controller) {
LoggerD("FlutterDestoryWindow");
controller->engine->EmbedderDestoryWindow();
controller->engine->DestroyWindow();
delete controller;
}

Expand Down Expand Up @@ -181,49 +181,44 @@ void FlutterDesktopMessengerSetCallback(FlutterDesktopMessengerRef messenger,
}

void FlutterNotifyLocaleChange(FlutterWindowControllerRef controller) {
if (!controller->engine) {
LoggerE("Tizen embedder engine isn't ready");
return;
if (controller->engine) {
controller->engine->SendLocales();
}
controller->engine->SendLocales();
}

void FlutterNotifyAppIsInactive(FlutterWindowControllerRef controller) {
if (!controller->engine) {
LoggerE("Tizen embedder engine isn't ready");
return;
if (controller->engine) {
controller->engine->AppIsInactive();
}
controller->engine->AppIsInactive();
}

void FlutterNotifyAppIsResumed(FlutterWindowControllerRef controller) {
if (!controller->engine) {
LoggerE("Tizen embedder engine isn't ready");
return;
if (controller->engine) {
controller->engine->AppIsResumed();
}
controller->engine->AppIsResumed();
}

void FlutterNotifyAppIsPaused(FlutterWindowControllerRef controller) {
if (!controller->engine) {
LoggerE("Tizen embedder engine isn't ready");
return;
if (controller->engine) {
controller->engine->AppIsPaused();
}
controller->engine->AppIsPaused();
}

void FlutterNotifyAppIsDetached(FlutterWindowControllerRef controller) {
if (!controller->engine) {
LoggerE("Tizen embedder engine isn't ready");
return;
if (controller->engine) {
controller->engine->AppIsDetached();
}
controller->engine->AppIsDetached();
}

void FlutterNotifyLowMemoryWarning(FlutterWindowControllerRef controller) {
if (!controller->engine->flutter_engine) {
LoggerE("Flutter engine isn't ready");
return;
if (controller->engine->flutter_engine) {
FlutterEngineNotifyLowMemoryWarning(controller->engine->flutter_engine);
}
}

void FlutterRotateWindow(FlutterWindowControllerRef controller,
int32_t degree) {
if (controller->engine) {
controller->engine->SetWindowOrientation(degree);
}
FlutterEngineNotifyLowMemoryWarning(controller->engine->flutter_engine);
}
3 changes: 3 additions & 0 deletions shell/platform/tizen/public/flutter_tizen.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,9 @@ FLUTTER_EXPORT void FlutterNotifyAppIsPaused(
FLUTTER_EXPORT void FlutterNotifyAppIsDetached(
FlutterWindowControllerRef controller);

FLUTTER_EXPORT void FlutterRotateWindow(FlutterWindowControllerRef controller,
int32_t degree);

#if defined(__cplusplus)
} // extern "C"
#endif
Expand Down
67 changes: 50 additions & 17 deletions shell/platform/tizen/tizen_embedder_engine.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,15 @@ TizenEmbedderEngine::TizenEmbedderEngine() { LoggerD("Flutter constructor"); }

TizenEmbedderEngine::~TizenEmbedderEngine() {}

bool TizenEmbedderEngine::EmbedderCreateWindow(
bool TizenEmbedderEngine::CreateWindow(
const FlutterWindowProperties& window_properties) {
tizen_surface_ = std::make_unique<TizenSurfaceGL>(
tizen_surface = std::make_unique<TizenSurfaceGL>(
window_properties.x, window_properties.y, window_properties.width,
window_properties.height);
return tizen_surface_->IsValid();
return tizen_surface->IsValid();
}

void TizenEmbedderEngine::EmbedderDestoryWindow() {
LoggerD("EmbedderDestoryWindow");
void TizenEmbedderEngine::DestroyWindow() {
if (flutter_engine) {
FlutterEngineShutdown(flutter_engine);
flutter_engine = nullptr;
Expand Down Expand Up @@ -71,7 +70,6 @@ UniqueAotDataPtr LoadAotData(std::string aot_data_path) {

bool TizenEmbedderEngine::RunFlutterEngine(
const FlutterEngineProperties& engine_properties) {
auto tizen_surface = tizen_surface_.get();
if (!tizen_surface->IsValid()) {
LoggerE("display was not valid.");
return false;
Expand Down Expand Up @@ -125,6 +123,7 @@ bool TizenEmbedderEngine::RunFlutterEngine(
config.open_gl.clear_current = ClearContext;
config.open_gl.present = Present;
config.open_gl.fbo_callback = GetActiveFbo;
config.open_gl.surface_transformation = Transformation;
config.open_gl.gl_proc_resolver = GlProcResolver;

FlutterProjectArgs args = {};
Expand Down Expand Up @@ -175,16 +174,16 @@ bool TizenEmbedderEngine::RunFlutterEngine(
internal_plugin_registrar_->messenger());
text_input_channel = std::make_unique<TextInputChannel>(
internal_plugin_registrar_->messenger(),
((TizenSurfaceGL*)tizen_surface)->wl2_window());
((TizenSurfaceGL*)tizen_surface.get())->wl2_window());
localization_channel = std::make_unique<LocalizationChannel>(flutter_engine);
localization_channel->SendLocales();
lifecycle_channel = std::make_unique<LifecycleChannel>(flutter_engine);

key_event_handler_ = std::make_unique<KeyEventHandler>(this);
touch_event_handler_ = std::make_unique<TouchEventHandler>(this);

SendWindowMetrics(tizen_surface_->GetWindowWidth(),
tizen_surface_->GetWindowHeight(), 0.0);
// This must be called to initialize the value of transformation_.
SetWindowOrientation(0);

return true;
}
Expand Down Expand Up @@ -238,10 +237,40 @@ void TizenEmbedderEngine::SendWindowMetrics(int32_t width, int32_t height,
FlutterEngineSendWindowMetricsEvent(flutter_engine, &event);
}

void TizenEmbedderEngine::SendLocales() {
localization_channel->SendLocales();
void TizenEmbedderEngine::SetWindowOrientation(int32_t degree) {
if (!tizen_surface) {
return;
}

// Compute renderer transformation based on the angle of rotation.
double rad = (360 - degree) * M_PI / 180;
double width = tizen_surface->GetWidth();
double height = tizen_surface->GetHeight();
double trans_x = 0.0, trans_y = 0.0;
if (degree == 90) {
trans_y = height;
} else if (degree == 180) {
trans_x = width;
trans_y = height;
} else if (degree == 270) {
trans_x = width;
}
transformation_ = {
cos(rad), -sin(rad), trans_x, // x
sin(rad), cos(rad), trans_y, // y
0.0, 0.0, 1.0 // perspective
};
touch_event_handler_->rotation = degree;

if (degree == 90 || degree == 270) {
SendWindowMetrics(height, width, 0.0);
} else {
SendWindowMetrics(width, height, 0.0);
}
}

void TizenEmbedderEngine::SendLocales() { localization_channel->SendLocales(); }

void TizenEmbedderEngine::AppIsInactive() {
lifecycle_channel->AppIsInactive();
}
Expand Down Expand Up @@ -289,30 +318,34 @@ FlutterDesktopMessage TizenEmbedderEngine::ConvertToDesktopMessage(

bool TizenEmbedderEngine::MakeContextCurrent(void* user_data) {
return reinterpret_cast<TizenEmbedderEngine*>(user_data)
->tizen_surface_->OnMakeCurrent();
->tizen_surface->OnMakeCurrent();
}

bool TizenEmbedderEngine::ClearContext(void* user_data) {
return reinterpret_cast<TizenEmbedderEngine*>(user_data)
->tizen_surface_->OnClearCurrent();
->tizen_surface->OnClearCurrent();
}

bool TizenEmbedderEngine::Present(void* user_data) {
return reinterpret_cast<TizenEmbedderEngine*>(user_data)
->tizen_surface_->OnPresent();
->tizen_surface->OnPresent();
}

bool TizenEmbedderEngine::MakeResourceCurrent(void* user_data) {
return reinterpret_cast<TizenEmbedderEngine*>(user_data)
->tizen_surface_->OnMakeResourceCurrent();
->tizen_surface->OnMakeResourceCurrent();
}

uint32_t TizenEmbedderEngine::GetActiveFbo(void* user_data) {
return reinterpret_cast<TizenEmbedderEngine*>(user_data)
->tizen_surface_->OnGetFBO();
->tizen_surface->OnGetFBO();
}

FlutterTransformation TizenEmbedderEngine::Transformation(void* user_data) {
return reinterpret_cast<TizenEmbedderEngine*>(user_data)->transformation_;
}

void* TizenEmbedderEngine::GlProcResolver(void* user_data, const char* name) {
return reinterpret_cast<TizenEmbedderEngine*>(user_data)
->tizen_surface_->OnProcResolver(name);
->tizen_surface->OnProcResolver(name);
}
19 changes: 13 additions & 6 deletions shell/platform/tizen/tizen_embedder_engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,11 @@ class TizenEmbedderEngine {
public:
TizenEmbedderEngine();
~TizenEmbedderEngine();
bool EmbedderCreateWindow(const FlutterWindowProperties& window_properties);
bool CreateWindow(const FlutterWindowProperties& window_properties);
void DestroyWindow();
bool RunFlutterEngine(const FlutterEngineProperties& engine_properties);
void EmbedderDestoryWindow();
FlutterDesktopPluginRegistrarRef GetPluginRegistrar();
void SendWindowMetrics(int32_t width, int32_t height, double pixel_ratio);
void SetWindowOrientation(int32_t degree);
void SendLocales();
void AppIsInactive();
void AppIsResumed();
Expand All @@ -77,7 +77,10 @@ class TizenEmbedderEngine {
// The Flutter engine instance.
FLUTTER_API_SYMBOL(FlutterEngine) flutter_engine;

// The system channels to communicate between Tizen and Flutter.
// The interface between the Flutter rasterizer and the platform.
std::unique_ptr<TizenSurface> tizen_surface;

// The system channels for communicating between Flutter and the platform.
std::unique_ptr<KeyEventChannel> key_event_channel;
std::unique_ptr<LifecycleChannel> lifecycle_channel;
std::unique_ptr<LocalizationChannel> localization_channel;
Expand All @@ -91,15 +94,16 @@ class TizenEmbedderEngine {
static bool Present(void* user_data);
static bool MakeResourceCurrent(void* user_data);
static uint32_t GetActiveFbo(void* user_data);
static FlutterTransformation Transformation(void* user_data);
static void* GlProcResolver(void* user_data, const char* name);
static void OnFlutterPlatformMessage(
const FlutterPlatformMessage* engine_message, void* user_data);
static void OnVsyncCallback(void* user_data, intptr_t baton);

void SendWindowMetrics(int32_t width, int32_t height, double pixel_ratio);
FlutterDesktopMessage ConvertToDesktopMessage(
const FlutterPlatformMessage& engine_message);

std::unique_ptr<TizenSurface> tizen_surface_;

// The handlers listening to platform events.
std::unique_ptr<KeyEventHandler> key_event_handler_;
std::unique_ptr<TouchEventHandler> touch_event_handler_;
Expand All @@ -121,5 +125,8 @@ class TizenEmbedderEngine {

// AOT data for this engine instance, if applicable.
UniqueAotDataPtr aot_data_ = nullptr;

// The current renderer transformation.
FlutterTransformation transformation_;
};
#endif // EMBEDDER_TIZEN_EMBEDDER_ENGINE_H_
31 changes: 2 additions & 29 deletions shell/platform/tizen/tizen_surface.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,38 +16,11 @@

#include "tizen_surface.h"

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

TizenSurface::TizenSurface(int32_t x, int32_t y, int32_t width, int32_t height)
: window_width_(width), window_height_(height), x_(x), y_(y) {}

TizenSurface::~TizenSurface() {}

uint32_t TizenSurface::GetWindowWidth() { return window_width_; }

uint32_t TizenSurface::GetWindowHeight() { return window_height_; }
uint32_t TizenSurface::GetWidth() { return window_width_; }

bool TizenSurface::OnMakeCurrent() {
LoggerD("TizenSurface::do nothing.....");
return false;
}
bool TizenSurface::OnClearCurrent() {
LoggerD("TizenSurface::do nothing.....");
return false;
}
bool TizenSurface::OnMakeResourceCurrent() {
LoggerD("TizenSurface::do nothing.....");
return false;
}
bool TizenSurface::OnPresent() {
LoggerD("TizenSurface::do nothing.....");
return false;
}
uint32_t TizenSurface::OnGetFBO() {
LoggerD("TizenSurface::do nothing.....");
return 0;
}
void* TizenSurface::OnProcResolver(const char* name) {
LoggerD("TizenSurface::do nothing.....");
return NULL;
}
uint32_t TizenSurface::GetHeight() { return window_height_; }
17 changes: 8 additions & 9 deletions shell/platform/tizen/tizen_surface.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,20 @@
#define EMBEDDER_TIZEN_SURFACE_H_

#include <string>
#include <vector>

class TizenSurface {
public:
TizenSurface(int32_t x, int32_t y, int32_t width, int32_t height);
virtual ~TizenSurface();
virtual bool OnMakeCurrent();
virtual bool OnClearCurrent();
virtual bool OnMakeResourceCurrent();
virtual bool OnPresent();
virtual uint32_t OnGetFBO();
virtual void* OnProcResolver(const char* name);
virtual bool OnMakeCurrent() = 0;
virtual bool OnClearCurrent() = 0;
virtual bool OnMakeResourceCurrent() = 0;
virtual bool OnPresent() = 0;
virtual uint32_t OnGetFBO() = 0;
virtual void* OnProcResolver(const char* name) = 0;
virtual bool IsValid() = 0;
uint32_t GetWindowWidth();
uint32_t GetWindowHeight();
uint32_t GetWidth();
uint32_t GetHeight();

protected:
const int32_t window_width_;
Expand Down
20 changes: 18 additions & 2 deletions shell/platform/tizen/touch_event_handler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,27 @@ void TouchEventHandler::SendFlutterPointerEvent(FlutterPointerPhase phase,
if (!engine_->flutter_engine) {
return;
}

// Correct errors caused by window rotation.
double width = engine_->tizen_surface->GetWidth();
double height = engine_->tizen_surface->GetHeight();
double new_x = x, new_y = y;
if (rotation == 90) {
new_x = height - y;
new_y = x;
} else if (rotation == 180) {
new_x = width - x;
new_y = height - y;
} else if (rotation == 270) {
new_x = y;
new_y = width - x;
}

FlutterPointerEvent event = {};
event.struct_size = sizeof(event);
event.phase = phase;
event.x = x;
event.y = y;
event.x = new_x;
event.y = new_y;
event.timestamp = timestamp;
FlutterEngineSendPointerEvent(engine_->flutter_engine, &event, 1);
}
Expand Down
Loading

0 comments on commit f63b250

Please sign in to comment.