2025-08-27 15:09:05 +09:00
|
|
|
#pragma once
|
|
|
|
|
|
2025-08-28 17:43:36 +09:00
|
|
|
#include "AnimationStrategy.h"
|
|
|
|
|
#include "TransitionStrategy.h"
|
2025-08-28 15:13:40 +09:00
|
|
|
#include "Preloader.h"
|
2025-08-27 15:09:05 +09:00
|
|
|
#include <string>
|
2025-08-28 15:13:40 +09:00
|
|
|
#include <sstream>
|
|
|
|
|
#include <iomanip>
|
|
|
|
|
#include <chrono>
|
2025-08-27 15:09:05 +09:00
|
|
|
#include <mutex>
|
2025-08-28 15:13:40 +09:00
|
|
|
#include <random>
|
2025-08-29 16:00:24 +09:00
|
|
|
#include <memory>
|
2025-08-27 15:09:05 +09:00
|
|
|
#include <android/native_window.h>
|
|
|
|
|
#include <android/native_window_jni.h>
|
|
|
|
|
|
|
|
|
|
class Renderer {
|
|
|
|
|
public:
|
2025-08-28 15:13:40 +09:00
|
|
|
enum class AnimationMode {
|
2025-08-29 16:00:24 +09:00
|
|
|
PAN = 0, ZOOM = 1, NONE = 2, RANDOM = 3,
|
|
|
|
|
PAN_ONE_WAY = 4, PAGE_TURN = 5
|
2025-08-28 15:13:40 +09:00
|
|
|
};
|
2025-08-28 17:43:36 +09:00
|
|
|
enum class TransitionMode {
|
2025-08-29 16:00:24 +09:00
|
|
|
FADE = 0, SLIDE = 1, RANDOM = 2, MOSAIC = 3
|
2025-08-28 17:43:36 +09:00
|
|
|
};
|
|
|
|
|
|
2025-08-27 15:09:05 +09:00
|
|
|
Renderer();
|
|
|
|
|
~Renderer();
|
|
|
|
|
|
|
|
|
|
void setNextMedia(int fd);
|
|
|
|
|
void renderFrame(ANativeWindow* window);
|
|
|
|
|
void release();
|
2025-08-28 15:13:40 +09:00
|
|
|
std::string getDebugInfo() const;
|
|
|
|
|
|
2025-08-29 18:01:53 +09:00
|
|
|
void startRenderLoop(ANativeWindow* window);
|
|
|
|
|
void stopRenderLoop();
|
|
|
|
|
|
2025-08-28 15:13:40 +09:00
|
|
|
void setAnimationSpeed(float speed);
|
|
|
|
|
void setAnimationMode(int mode);
|
|
|
|
|
void setFadeDuration(int durationMs);
|
2025-08-28 17:43:36 +09:00
|
|
|
void setPageTurnDelay(int delayMs);
|
|
|
|
|
void setTransitionMode(int mode);
|
|
|
|
|
|
2025-08-28 18:13:46 +09:00
|
|
|
void drawMedia(ANativeWindow_Buffer& buffer, MediaAsset& media, float alpha, float finalOffsetX, float finalOffsetY, float finalScale);
|
2025-08-28 17:43:36 +09:00
|
|
|
void renderVideoFrame(MediaAsset& media, ANativeWindow_Buffer& buffer, float scale, float offsetX, float offsetY, float alpha);
|
|
|
|
|
void renderImageFrame(const MediaAsset& media, ANativeWindow_Buffer& buffer, float scale, float offsetX, float offsetY, float alpha);
|
2025-08-28 18:13:46 +09:00
|
|
|
void calculateFitScaleAndOffset(const MediaAsset& media, int surfaceWidth, int surfaceHeight,
|
|
|
|
|
float& outScale, float& outOffsetX, float& outOffsetY) const;
|
2025-08-27 15:09:05 +09:00
|
|
|
|
|
|
|
|
private:
|
2025-08-29 18:01:53 +09:00
|
|
|
|
|
|
|
|
std::thread renderThread_;
|
|
|
|
|
std::atomic<bool> isRunning_{false};
|
|
|
|
|
ANativeWindow* nativeWindow_ = nullptr;
|
|
|
|
|
|
2025-08-29 16:00:24 +09:00
|
|
|
enum class RenderState { ANIMATING, TRANSITIONING };
|
2025-08-28 18:13:46 +09:00
|
|
|
RenderState currentState_ = RenderState::ANIMATING;
|
2025-08-29 16:00:24 +09:00
|
|
|
|
2025-08-28 18:13:46 +09:00
|
|
|
void handleAnimationState(ANativeWindow_Buffer& buffer, int surfaceWidth, int surfaceHeight);
|
|
|
|
|
void handleTransitionState(ANativeWindow_Buffer& buffer, int surfaceWidth, int surfaceHeight);
|
2025-08-28 17:43:36 +09:00
|
|
|
|
2025-08-28 18:13:46 +09:00
|
|
|
std::mutex renderMutex_;
|
2025-08-28 15:13:40 +09:00
|
|
|
Preloader preloader_;
|
2025-08-27 15:09:05 +09:00
|
|
|
MediaAsset currentMedia_;
|
|
|
|
|
MediaAsset nextMedia_;
|
2025-08-29 16:00:24 +09:00
|
|
|
|
2025-08-28 17:43:36 +09:00
|
|
|
std::unique_ptr<AnimationStrategy> animationStrategy_;
|
2025-08-29 16:00:24 +09:00
|
|
|
AnimationMode predictedNextAnimationMode_;
|
2025-08-28 17:43:36 +09:00
|
|
|
std::unique_ptr<TransitionStrategy> transitionStrategy_;
|
2025-08-29 16:00:24 +09:00
|
|
|
AnimationState lastAnimationState_;
|
2025-08-27 15:09:05 +09:00
|
|
|
|
2025-08-28 15:13:40 +09:00
|
|
|
AnimationMode configuredAnimationMode_ = AnimationMode::PAN;
|
2025-08-28 17:43:36 +09:00
|
|
|
TransitionMode configuredTransitionMode_ = TransitionMode::FADE;
|
2025-08-28 15:13:40 +09:00
|
|
|
AnimationMode activeAnimationMode_ = AnimationMode::PAN;
|
|
|
|
|
long long fadeDurationMs_ = 3000;
|
2025-08-28 17:43:36 +09:00
|
|
|
long long pageTurnDelayMs_ = 5000;
|
2025-08-28 15:13:40 +09:00
|
|
|
float animationSpeed_ = 1.0f;
|
2025-08-29 18:01:53 +09:00
|
|
|
// --- ⬇️ 목표 프레임 딜레이 변수 추가 ⬇️ ---
|
|
|
|
|
std::chrono::milliseconds currentFrameDelay_{33}; // 기본값 33ms (약 30fps)
|
2025-08-28 15:13:40 +09:00
|
|
|
|
2025-08-29 16:00:24 +09:00
|
|
|
AnimationState getStartStateForMode(AnimationMode mode, int surfaceWidth, int surfaceHeight);
|
|
|
|
|
AnimationMode predictNextAnimationMode();
|
2025-08-28 15:13:40 +09:00
|
|
|
|
2025-08-29 16:00:24 +09:00
|
|
|
std::chrono::steady_clock::time_point transitionStartTime_;
|
2025-08-28 15:13:40 +09:00
|
|
|
std::mt19937 randomEngine_;
|
|
|
|
|
|
|
|
|
|
void determineActiveAnimationMode();
|
2025-08-27 15:09:05 +09:00
|
|
|
};
|