diff --git a/docker-scripts/docker_build_android_libraries b/docker-scripts/docker_build_android_libraries index 0b30e9a..2ba4259 100644 --- a/docker-scripts/docker_build_android_libraries +++ b/docker-scripts/docker_build_android_libraries @@ -5,11 +5,20 @@ SFML_FOLDER=$2 STL_CHOSEN=$3 RELEASE_TYPE=$4 +CONFIGURE_SINGLE_ARCH_SFML_COMMAND=docker-scripts/docker_config_android_sfml_single_arch BUILD_SINGLE_ARCH_SFML_COMMAND=docker-scripts/docker_build_android_sfml_single_arch -(cd ${LIBUSB_FOLDER}/android/jni ; ndk-build APP_PLATFORM=${ANDROID_SDK_VERSION} ; mkdir -p ${ANDROID_NDK_HOME}/sources/third_party/libusb/include ; cp -r ../libs/ ${ANDROID_NDK_HOME}/sources/third_party/libusb ; cp -r ../../libusb ${ANDROID_NDK_HOME}/sources/third_party/libusb/include) +(cd ${LIBUSB_FOLDER}/android/jni ; ndk-build APP_PLATFORM=${ANDROID_SDK_VERSION} -j ; mkdir -p ${ANDROID_NDK_HOME}/sources/third_party/libusb/include ; cp -r ../libs/ ${ANDROID_NDK_HOME}/sources/third_party/libusb ; cp -r ../../libusb ${ANDROID_NDK_HOME}/sources/third_party/libusb/include) -${BUILD_SINGLE_ARCH_SFML_COMMAND} ${SFML_FOLDER} armeabi-v7a ${STL_CHOSEN} ${RELEASE_TYPE} -${BUILD_SINGLE_ARCH_SFML_COMMAND} ${SFML_FOLDER} arm64-v8a ${STL_CHOSEN} ${RELEASE_TYPE} -${BUILD_SINGLE_ARCH_SFML_COMMAND} ${SFML_FOLDER} x86 ${STL_CHOSEN} ${RELEASE_TYPE} -${BUILD_SINGLE_ARCH_SFML_COMMAND} ${SFML_FOLDER} x86_64 ${STL_CHOSEN} ${RELEASE_TYPE} +${CONFIGURE_SINGLE_ARCH_SFML_COMMAND} ${SFML_FOLDER} armeabi-v7a ${STL_CHOSEN} ${RELEASE_TYPE} & +${CONFIGURE_SINGLE_ARCH_SFML_COMMAND} ${SFML_FOLDER} arm64-v8a ${STL_CHOSEN} ${RELEASE_TYPE} & +${CONFIGURE_SINGLE_ARCH_SFML_COMMAND} ${SFML_FOLDER} x86 ${STL_CHOSEN} ${RELEASE_TYPE} & +${CONFIGURE_SINGLE_ARCH_SFML_COMMAND} ${SFML_FOLDER} x86_64 ${STL_CHOSEN} ${RELEASE_TYPE} + +wait $(jobs -p) +echo "All libraries configured..." + +${BUILD_SINGLE_ARCH_SFML_COMMAND} ${SFML_FOLDER} armeabi-v7a +${BUILD_SINGLE_ARCH_SFML_COMMAND} ${SFML_FOLDER} arm64-v8a +${BUILD_SINGLE_ARCH_SFML_COMMAND} ${SFML_FOLDER} x86 +${BUILD_SINGLE_ARCH_SFML_COMMAND} ${SFML_FOLDER} x86_64 diff --git a/docker-scripts/docker_build_android_sfml_single_arch b/docker-scripts/docker_build_android_sfml_single_arch index a68ecf8..457343e 100644 --- a/docker-scripts/docker_build_android_sfml_single_arch +++ b/docker-scripts/docker_build_android_sfml_single_arch @@ -2,8 +2,5 @@ SFML_FOLDER=$1 ARCH_CHOSEN=$2 -STL_CHOSEN=$3 -RELEASE_TYPE=$4 -(cd ${SFML_FOLDER} ; mkdir -p build/${ARCH_CHOSEN}) -(cd ${SFML_FOLDER}/build/${ARCH_CHOSEN} ; cmake -DCMAKE_SYSTEM_NAME=Android -DCMAKE_ANDROID_NDK=${ANDROID_NDK_HOME} -DCMAKE_ANDROID_ARCH_ABI=${ARCH_CHOSEN} -DCMAKE_ANDROID_STL_TYPE=${STL_CHOSEN} -DCMAKE_BUILD_TYPE=${RELEASE_TYPE} ../.. ; make ; make install) +(cd ${SFML_FOLDER}/build/${ARCH_CHOSEN} ; make -j ; make install) diff --git a/docker-scripts/docker_config_android_sfml_single_arch b/docker-scripts/docker_config_android_sfml_single_arch new file mode 100644 index 0000000..ad1f764 --- /dev/null +++ b/docker-scripts/docker_config_android_sfml_single_arch @@ -0,0 +1,9 @@ +#!/bin/sh + +SFML_FOLDER=$1 +ARCH_CHOSEN=$2 +STL_CHOSEN=$3 +RELEASE_TYPE=$4 + +(cd ${SFML_FOLDER} ; mkdir -p build/${ARCH_CHOSEN}) +(cd ${SFML_FOLDER}/build/${ARCH_CHOSEN} ; cmake -DCMAKE_SYSTEM_NAME=Android -DCMAKE_ANDROID_NDK=${ANDROID_NDK_HOME} -DCMAKE_ANDROID_ARCH_ABI=${ARCH_CHOSEN} -DCMAKE_ANDROID_STL_TYPE=${STL_CHOSEN} -DCMAKE_BUILD_TYPE=${RELEASE_TYPE} ../.. ) diff --git a/include/TextRectangle.hpp b/include/TextRectangle.hpp index 3e780c6..6a47ff9 100755 --- a/include/TextRectangle.hpp +++ b/include/TextRectangle.hpp @@ -26,6 +26,8 @@ public: void setText(std::string text); void setShowText(bool show_text); void draw(sf::RenderTarget &window); + // Only applies to text displayed with timer set to true + bool isTimerTextDone(); private: out_rect_data text_rect; diff --git a/include/conversions.hpp b/include/conversions.hpp index 97d36fa..443d082 100755 --- a/include/conversions.hpp +++ b/include/conversions.hpp @@ -7,5 +7,6 @@ bool convertVideoToOutput(VideoOutputData *p_out, const bool is_big_endian, CaptureDataSingleBuffer* data_buffer, CaptureStatus* status, bool interleaved_3d); bool convertAudioToOutput(std::int16_t *p_out, uint64_t &n_samples, uint16_t &last_buffer_index, const bool is_big_endian, CaptureDataSingleBuffer* data_buffer, CaptureStatus* status); void manualConvertOutputToRGB(VideoOutputData* src, VideoOutputData* dst, size_t pos_x_data, size_t pos_y_data, size_t width, size_t height, InputVideoDataType video_data_type); +void manualConvertOutputToRGBA(VideoOutputData* src, VideoOutputData* dst, size_t pos_x_data, size_t pos_y_data, size_t width, size_t height, InputVideoDataType video_data_type); #endif diff --git a/include/display_structs.hpp b/include/display_structs.hpp index 9c46cdd..2f9dd34 100755 --- a/include/display_structs.hpp +++ b/include/display_structs.hpp @@ -139,6 +139,13 @@ struct PACKED VideoPixelBGR { uint8_t r; }; +struct PACKED VideoPixelRGBA { + uint8_t r; + uint8_t g; + uint8_t b; + uint8_t alpha; +}; + struct PACKED ALIGNED(16) VideoOutputDataRGB16 { VideoPixelRGB16 screen_data[MAX_IN_VIDEO_SIZE]; }; @@ -155,11 +162,16 @@ struct PACKED ALIGNED(16) VideoOutputDataBGR { VideoPixelBGR screen_data[MAX_IN_VIDEO_SIZE]; }; +struct PACKED ALIGNED(16) VideoOutputDataRGBA { + VideoPixelRGBA screen_data[MAX_IN_VIDEO_SIZE]; +}; + union PACKED ALIGNED(16) VideoOutputData { VideoOutputDataRGB16 rgb16_video_output_data; VideoOutputDataBGR16 bgr16_video_output_data; VideoOutputDataRGB rgb_video_output_data; VideoOutputDataBGR bgr_video_output_data; + VideoOutputDataRGBA rgba_video_output_data; }; #pragma pack(pop) diff --git a/include/frontend.hpp b/include/frontend.hpp index 0e8db8d..5f75a22 100755 --- a/include/frontend.hpp +++ b/include/frontend.hpp @@ -95,6 +95,7 @@ public: private: enum PossibleShaderTypes { BASE_INPUT_SHADER_TYPE, BASE_FINAL_OUTPUT_SHADER_TYPE, COLOR_PROCESSING_SHADER_TYPE }; + enum PossibleSoftwareConvTypes { NO_SOFTWARE_CONV, TO_RGB_SOFTWARE_CONV, TO_RGBA_SOFTWARE_CONV }; struct ScreenOperations { bool call_create; bool call_close; @@ -115,7 +116,7 @@ private: }; OutTextData own_out_text_data; InputVideoDataType last_update_texture_data_type; - bool use_texture_software_based_conv; + PossibleSoftwareConvTypes texture_software_based_conv; bool created_proper_folder; CaptureStatus* capture_status; std::string win_title; diff --git a/source/TextRectangle.cpp b/source/TextRectangle.cpp index 0634970..02f7d7d 100755 --- a/source/TextRectangle.cpp +++ b/source/TextRectangle.cpp @@ -3,6 +3,7 @@ TextRectangle::TextRectangle(bool font_load_success, sf::Font &text_font) : actual_text(text_font) { this->reset_data(this->future_data); this->font_load_success = font_load_success; + this->is_done_showing_text = true; this->setRealSize(1, 1, false); this->text_rect.out_rect.setTexture(&this->text_rect.out_tex.getTexture()); if(this->font_load_success) @@ -267,6 +268,11 @@ void TextRectangle::updateText(int x_limit) { this->loaded_data.start_timer = this->loaded_data.is_timed; } +// Only applies to text displayed with timer set to true +bool TextRectangle::isTimerTextDone() { + return this->is_done_showing_text; +} + void TextRectangle::updateSlides(float* time_seconds) { time_seconds[0] = base_time_slide_factor * (this->loaded_data.height / (loaded_data.font_pixel_height * base_pixel_slide_factor)); time_seconds[1] = loaded_data.duration; diff --git a/source/WindowScreen.cpp b/source/WindowScreen.cpp index 243e547..0776e41 100755 --- a/source/WindowScreen.cpp +++ b/source/WindowScreen.cpp @@ -62,7 +62,7 @@ WindowScreen::WindowScreen(ScreenType stype, CaptureStatus* capture_status, Disp FPSArrayInit(&this->draw_fps); FPSArrayInit(&this->poll_fps); this->last_update_texture_data_type = VIDEO_DATA_RGB; - this->use_texture_software_based_conv = false; + this->texture_software_based_conv = NO_SOFTWARE_CONV; this->num_frames_to_blend = NUM_FRAMES_BLENDED; if(disable_frame_blending) this->num_frames_to_blend = 1; @@ -568,7 +568,7 @@ sf::String WindowScreen::title_factory() { #endif void WindowScreen::opengl_error_out(std::string error_base, std::string error_str) { - UpdateOutText(this->own_out_text_data, error_base + ": " + error_str, error_base, TEXT_KIND_ERROR); + UpdateOutText(this->own_out_text_data, error_base + ": " + error_str, error_base + ": " + error_str, TEXT_KIND_ERROR); } void WindowScreen::opengl_error_check(std::string error_base) { @@ -591,6 +591,9 @@ bool WindowScreen::single_update_texture(unsigned int m_texture, InputVideoDataT GLenum type = GL_UNSIGNED_BYTE; size_t format_size = sizeof(VideoPixelRGB); + if(manually_converted && (this->texture_software_based_conv == TO_RGBA_SOFTWARE_CONV)) + format = GL_RGBA; + if(!manually_converted) { if(video_data_type == VIDEO_DATA_BGR) { format = GL_BGR; @@ -615,7 +618,15 @@ bool WindowScreen::single_update_texture(unsigned int m_texture, InputVideoDataT if((format != GL_RGB) || (type != GL_UNSIGNED_BYTE)) { UpdateOutText(this->own_out_text_data, "Switching to software-based texture updating", "", TEXT_KIND_NORMAL); this->last_update_texture_data_type = video_data_type; - this->use_texture_software_based_conv = true; + this->texture_software_based_conv = TO_RGB_SOFTWARE_CONV; + return true; + } + } + if(glCheckInternalError == GL_INVALID_OPERATION) { + if((format != GL_RGBA) || (type != GL_UNSIGNED_BYTE)) { + UpdateOutText(this->own_out_text_data, "Switching to software-based texture updating", "", TEXT_KIND_NORMAL); + this->last_update_texture_data_type = video_data_type; + this->texture_software_based_conv = TO_RGBA_SOFTWARE_CONV; return true; } } @@ -710,12 +721,22 @@ void WindowScreen::execute_single_update_texture(bool &manually_converted, bool unsigned int m_texture = target_texture->getNativeHandle(); bool retry = true; while(retry) { - bool software_based_conv = manually_converted || (this->use_texture_software_based_conv && (video_data_type == this->last_update_texture_data_type)); + bool software_based_conv = manually_converted || ((this->texture_software_based_conv != NO_SOFTWARE_CONV) && (video_data_type == this->last_update_texture_data_type)); + if(software_based_conv) { - if(!manually_converted) - manualConvertOutputToRGB(this->saved_buf, this->saved_buf, pos_x_conv, pos_y_conv, full_width, full_height, video_data_type); + if(!manually_converted) { + if(this->texture_software_based_conv == TO_RGB_SOFTWARE_CONV) + manualConvertOutputToRGB(this->saved_buf, this->saved_buf, pos_x_conv, pos_y_conv, full_width, full_height, video_data_type); + if(this->texture_software_based_conv == TO_RGBA_SOFTWARE_CONV) + manualConvertOutputToRGBA(this->saved_buf, this->saved_buf, pos_x_conv, pos_y_conv, full_width, full_height, video_data_type); + } manually_converted = true; } + else { + this->texture_software_based_conv = NO_SOFTWARE_CONV; + this->last_update_texture_data_type = video_data_type; + } + retry = this->single_update_texture(m_texture, video_data_type, pos_x_data, pos_y_data, width, height, manually_converted); } } @@ -1849,7 +1870,7 @@ void WindowScreen::setWinSize(bool is_main_thread) { void WindowScreen::process_own_out_text_data(bool print_to_notification) { if(!this->own_out_text_data.consumed) { ConsumeOutText(this->own_out_text_data, false); - if(print_to_notification) + if(print_to_notification && this->notification->isTimerTextDone()) this->print_notification(this->own_out_text_data.small_text, this->own_out_text_data.kind); this->own_out_text_data.consumed = true; } diff --git a/source/conversions.cpp b/source/conversions.cpp index a53a16f..17f6c19 100755 --- a/source/conversions.cpp +++ b/source/conversions.cpp @@ -1075,3 +1075,83 @@ void manualConvertOutputToRGB(VideoOutputData* src, VideoOutputData* dst, size_t break; } } + +static void convert_rgb_to_rgba(VideoOutputData* src, VideoOutputData* dst, size_t pos_x_data, size_t pos_y_data, size_t width, size_t height) { + for (size_t i = 0; i < height; i++) { + for (size_t j = 0; j < width; j++) { + size_t pixel = ((height - 1 - i) * width) + (width - 1 - j) + pos_x_data + (pos_y_data * width); + uint8_t r = src->rgb_video_output_data.screen_data[pixel].r; + uint8_t g = src->rgb_video_output_data.screen_data[pixel].g; + uint8_t b = src->rgb_video_output_data.screen_data[pixel].b; + dst->rgba_video_output_data.screen_data[pixel].r = r; + dst->rgba_video_output_data.screen_data[pixel].g = g; + dst->rgba_video_output_data.screen_data[pixel].b = b; + dst->rgba_video_output_data.screen_data[pixel].alpha = 0xFF; + } + } +} + +static void convert_rgb16_to_rgba(VideoOutputData* src, VideoOutputData* dst, size_t pos_x_data, size_t pos_y_data, size_t width, size_t height) { + for (size_t i = 0; i < height; i++) { + for (size_t j = 0; j < width; j++) { + size_t pixel = ((height - 1 - i) * width) + (width - 1 - j) + pos_x_data + (pos_y_data * width); + uint8_t r = to_8_bit_5(src->rgb16_video_output_data.screen_data[pixel].r); + uint8_t g = to_8_bit_6(src->rgb16_video_output_data.screen_data[pixel].g); + uint8_t b = to_8_bit_5(src->rgb16_video_output_data.screen_data[pixel].b); + dst->rgba_video_output_data.screen_data[pixel].r = r; + dst->rgba_video_output_data.screen_data[pixel].g = g; + dst->rgba_video_output_data.screen_data[pixel].b = b; + dst->rgba_video_output_data.screen_data[pixel].alpha = 0xFF; + } + } +} + +static void convert_bgr_to_rgba(VideoOutputData* src, VideoOutputData* dst, size_t pos_x_data, size_t pos_y_data, size_t width, size_t height) { + for (size_t i = 0; i < height; i++) { + for (size_t j = 0; j < width; j++) { + size_t pixel = ((height - 1 - i) * width) + (width - 1 - j) + pos_x_data + (pos_y_data * width); + uint8_t r = src->bgr_video_output_data.screen_data[pixel].r; + uint8_t g = src->bgr_video_output_data.screen_data[pixel].g; + uint8_t b = src->bgr_video_output_data.screen_data[pixel].b; + dst->rgba_video_output_data.screen_data[pixel].r = r; + dst->rgba_video_output_data.screen_data[pixel].g = g; + dst->rgba_video_output_data.screen_data[pixel].b = b; + dst->rgba_video_output_data.screen_data[pixel].alpha = 0xFF; + } + } +} + +static void convert_bgr16_to_rgba(VideoOutputData* src, VideoOutputData* dst, size_t pos_x_data, size_t pos_y_data, size_t width, size_t height) { + uint16_t* data_16_ptr = (uint16_t*)src; + for (size_t i = 0; i < height; i++) { + for (size_t j = 0; j < width; j++) { + size_t pixel = ((height - 1 - i) * width) + (width - 1 - j) + pos_x_data + (pos_y_data * width); + uint8_t r = to_8_bit_5(src->bgr16_video_output_data.screen_data[pixel].r); + uint8_t g = to_8_bit_6(src->bgr16_video_output_data.screen_data[pixel].g); + uint8_t b = to_8_bit_5(src->bgr16_video_output_data.screen_data[pixel].b); + dst->rgba_video_output_data.screen_data[pixel].r = r; + dst->rgba_video_output_data.screen_data[pixel].g = g; + dst->rgba_video_output_data.screen_data[pixel].b = b; + dst->rgba_video_output_data.screen_data[pixel].alpha = 0xFF; + } + } +} + +void manualConvertOutputToRGBA(VideoOutputData* src, VideoOutputData* dst, size_t pos_x_data, size_t pos_y_data, size_t width, size_t height, InputVideoDataType video_data_type) { + switch (video_data_type) { + case VIDEO_DATA_RGB: + convert_rgb_to_rgba(src, dst, pos_x_data, pos_y_data, width, height); + break; + case VIDEO_DATA_RGB16: + convert_rgb16_to_rgba(src, dst, pos_x_data, pos_y_data, width, height); + break; + case VIDEO_DATA_BGR: + convert_bgr_to_rgba(src, dst, pos_x_data, pos_y_data, width, height); + break; + case VIDEO_DATA_BGR16: + convert_bgr16_to_rgba(src, dst, pos_x_data, pos_y_data, width, height); + break; + default: + break; + } +}