Skip to content

Commit

Permalink
added pooling
Browse files Browse the repository at this point in the history
  • Loading branch information
redrezo committed Sep 17, 2019
1 parent e9a4388 commit c99cccf
Show file tree
Hide file tree
Showing 34 changed files with 605 additions and 164 deletions.
1 change: 1 addition & 0 deletions native/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ set(CMAKE_CXX_STANDARD 11)

# configure debug symbols
if (LINUX)
# set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ggdb")
set(CMAKE_CXX_CREATE_SHARED_LIBRARY
"${CMAKE_CXX_CREATE_SHARED_LIBRARY}"
"${CMAKE_OBJCOPY} --only-keep-debug <TARGET> <TARGET>.debug"
Expand Down
5 changes: 3 additions & 2 deletions native/DriftFX/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
cmake_minimum_required(VERSION 3.1)
project(DriftFX CXX)



# configuring msvc to include the runtime
#if (WIN32)
#set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
Expand Down Expand Up @@ -82,6 +80,9 @@ set(DriftFX-Sources
src/NoOpTransferMode.cpp

src/GPUSyncUtil.cpp

src/SharedTexturePool.h
src/SharedTexturePool.cpp
)

if (WIN32)
Expand Down
2 changes: 2 additions & 0 deletions native/DriftFX/include/DriftFX/math/Vec2.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ typedef Vec2<int> Vec2i;
typedef Vec2<unsigned int> Vec2ui;
typedef Vec2<double> Vec2d;



}
}

Expand Down
22 changes: 15 additions & 7 deletions native/DriftFX/src/FrameManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,24 +39,21 @@ Frame::Frame(long surfaceId, long long frameId, SurfaceData surfaceData, math::V
}

Frame::~Frame() {
LogDebug("Destroying Frame " << dec << surfaceId << "." << dec << frameId);
if (sharedTexture != nullptr) {
delete sharedTexture;
}
if (frameData != nullptr) {
delete frameData;
frameData = nullptr;
}
}

void Frame::SetData(ShareData* data) {
this->frameData = data;
}
ShareData* Frame::GetData() {
return this->frameData;
}

void Frame::SetSharedTexture(SharedTexture* texture) {
sharedTexture = texture;
if (texture != nullptr) {
frameData = texture->CreateShareData();
}
}

SharedTexture* Frame::GetSharedTexture() {
Expand Down Expand Up @@ -97,6 +94,16 @@ std::string Frame::ToString() {
return s.str();
}

std::string Frame::TimeReport() {
ostringstream s;
auto clientDuration = std::chrono::duration_cast<std::chrono::nanoseconds>(presentBegin - acquireEnd);
auto acquireDuration = std::chrono::duration_cast<std::chrono::nanoseconds>(acquireEnd - acquireBegin);
auto presentDuration = std::chrono::duration_cast<std::chrono::nanoseconds>(presentEnd - presentBegin);
auto fxPresentDuration = std::chrono::duration_cast<std::chrono::nanoseconds>(fxPresentEnd - fxPresentBegin);
s << "Frame(" << dec << surfaceId << "." << dec << frameId << "| acquire: " << acquireDuration.count() << "ns, client: " << clientDuration.count() <<"ns, present: " << presentDuration.count() << "ns, fxPresent: " << fxPresentDuration.count() << "ns)";
return s.str();
}

math::Vec2ui Frame::GetSize() {
return size;
}
Expand Down Expand Up @@ -130,6 +137,7 @@ Frame* FrameManager::GetFrame(long long frameId) {
}

void FrameManager::DisposeFrame(long long frameId) {
LogDebug("Dispose Frame #" << frameId);
framesMutex.lock();
Frame* frame = frames[frameId];
frames.erase(frameId);
Expand Down
17 changes: 16 additions & 1 deletion native/DriftFX/src/FrameManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,16 @@
#ifndef DRIFTFX_INTERNAL_FRAMEMANAGER_H_
#define DRIFTFX_INTERNAL_FRAMEMANAGER_H_


// windows header conflicts with chronos min -.-
#ifdef min
#undef min
#endif

#include <map>
#include <vector>
#include <mutex>
#include <chrono>

#include <DriftFX/DriftFXSurface.h>
#include <DriftFX/math/Vec2.h>
Expand All @@ -41,7 +48,6 @@ class Frame : public RenderTarget {
virtual void SetPresentationHint(PresentationHint hint);

virtual ShareData* GetData();
virtual void SetData(ShareData* data);

virtual SharedTexture* GetSharedTexture();

Expand All @@ -58,6 +64,15 @@ class Frame : public RenderTarget {
virtual PresentationHint GetPresentationHint();

virtual std::string ToString();
virtual std::string TimeReport();


std::chrono::steady_clock::time_point acquireBegin = std::chrono::steady_clock::time_point::min();
std::chrono::steady_clock::time_point acquireEnd = std::chrono::steady_clock::time_point::min();
std::chrono::steady_clock::time_point presentBegin = std::chrono::steady_clock::time_point::min();
std::chrono::steady_clock::time_point presentEnd = std::chrono::steady_clock::time_point::min();
std::chrono::steady_clock::time_point fxPresentBegin = std::chrono::steady_clock::time_point::min();
std::chrono::steady_clock::time_point fxPresentEnd = std::chrono::steady_clock::time_point::min();

private:
long surfaceId;
Expand Down
54 changes: 35 additions & 19 deletions native/DriftFX/src/MainMemorySharedTexture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,28 +37,51 @@ using namespace driftfx::internal;



MainMemorySharedTexture::MainMemorySharedTexture(GLContext* context, Frame* frame)
: SharedTexture(context, frame),
size(frame->GetSize().x * frame->GetSize().y * 4),
MainMemorySharedTexture::MainMemorySharedTexture(GLContext* context, math::Vec2ui size)
: SharedTexture(context, size),
memSize(size.x * size.y * 4),
pointer(nullptr) {

Allocate();
}

MainMemorySharedTexture::~MainMemorySharedTexture() {
LogDebug("Freeing memory");
free(pointer);
pointer = nullptr;
Release();
}

bool MainMemorySharedTexture::BeforeRender() {
ShareData* MainMemorySharedTexture::CreateShareData() {
MainMemoryShareData* data = new MainMemoryShareData();
data->pointer = pointer;
data->length = memSize;
return data;
}

void MainMemorySharedTexture::Allocate() {
auto begin = std::chrono::steady_clock::now();

// prepare the texture
auto textureSize = frame->GetSize();
glTexture = dynamic_cast<GLTexture*>(glContext->CreateTexture(textureSize.x, textureSize.y));
glTexture = dynamic_cast<GLTexture*>(glContext->CreateTexture(size.x, size.y));

GLCALL( glBindTexture(GL_TEXTURE_2D, glTexture->Name()) );
GLCALL( glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, textureSize.x, textureSize.y, 0, GL_BGRA, GL_UNSIGNED_BYTE, 0) );
GLCALL( glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.x, size.y, 0, GL_BGRA, GL_UNSIGNED_BYTE, 0) );
GLCALL( glBindTexture(GL_TEXTURE_2D, 0) );

// prepare the memory
pointer = malloc(memSize);

auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now() - begin);
LogDebug("allocation needed " << duration.count() << "ns");
}

void MainMemorySharedTexture::Release() {
// release texture
delete glTexture;
// release memory
free(pointer);
pointer = nullptr;
}

bool MainMemorySharedTexture::BeforeRender() {
return true;
}

Expand All @@ -68,8 +91,6 @@ bool MainMemorySharedTexture::AfterRender() {
// TODO move the download operation to another thread
DownloadToMemory();

delete glTexture;

return true;
}

Expand Down Expand Up @@ -113,17 +134,12 @@ void DownloadToMemoryBuf(unsigned int tex, unsigned int size, void* pointer) {
}

void MainMemorySharedTexture::DownloadToMemory() {
// allocate
pointer = malloc(size);
WaitForFrameReady();
// download pixel data
auto begin = std::chrono::steady_clock::now();
DownloadToMemoryBuf(GetTexture()->Name(), size, pointer);
DownloadToMemoryBuf(GetTexture()->Name(), memSize, pointer);
auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now() - begin);
LogDebug("download frame needed " << duration.count() << "ns");

MainMemoryShareData* data = new MainMemoryShareData();
data->pointer = pointer;
data->length = size;
frame->SetData(data);

}
8 changes: 6 additions & 2 deletions native/DriftFX/src/MainMemorySharedTexture.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,21 +33,25 @@ class MainMemoryShareData : public ShareData {
class MainMemorySharedTexture : public SharedTexture {

public:
MainMemorySharedTexture(GLContext* context, Frame* frame);
MainMemorySharedTexture(GLContext* context, math::Vec2ui size);
virtual ~MainMemorySharedTexture();

virtual bool BeforeRender();
virtual bool AfterRender();

virtual ShareData* CreateShareData();

protected:

virtual void Allocate();
virtual void Release();

void DownloadToMemory();


private:

unsigned long size;
unsigned long memSize;
void* pointer;


Expand Down
75 changes: 70 additions & 5 deletions native/DriftFX/src/NativeSurface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "JNINativeSurface.h"
#include "NativeSurface.h"
#include "SharedTexture.h"
#include "SharedTexturePool.h"
#include "prism/PrismBridge.h"

#include <utils/Logger.h>
Expand All @@ -42,7 +43,8 @@ NativeSurface::NativeSurface(long surfaceId, JNINativeSurface* api) :
api(api),
context(nullptr),
surfaceData(SurfaceData()),
frameManager(surfaceId) {
frameManager(surfaceId),
texturePool() {
LogDebug("NativeSurface constructor")

}
Expand All @@ -59,6 +61,10 @@ void NativeSurface::Initialize() {
}

void NativeSurface::Cleanup() {

// TODO we need to make sure that every SharedTexture is gone
// however atm fx holds the last texture until we send a new one..

// // TODO send some kind of signal to tell FX we are going to dispose our textures
// FrameData* frameData = new FrameData();
// frameData->d3dSharedHandle = 0;
Expand All @@ -76,6 +82,19 @@ void NativeSurface::Cleanup() {
// NOTE: since textures know their context and set it current upon deletion
// we must ensure that all textures from a context are deleted before the context is deleted!


// we need to clean the pools, since our context becomes invalid
texturePoolMutex.lock();
std::map<unsigned int, SharedTexturePool*>::iterator it;
for (it = texturePool.begin(); it != texturePool.end(); it++) {
auto pool = (*it).second;
LogDebug("Deleting Texture Pool " << pool);
delete pool;
}
texturePool.clear();
LogDebug("Cleared pools " << texturePool.size());
texturePoolMutex.unlock();

LogDebug("clean GLContext");
delete context;
context = nullptr;
Expand Down Expand Up @@ -137,6 +156,7 @@ RenderTarget* NativeSurface::Acquire(unsigned int width, unsigned int height, dr
}

RenderTarget* NativeSurface::Acquire(math::Vec2ui size, SurfaceData surfaceData) {
auto begin = std::chrono::steady_clock::now();
PrismBridge* bridge = PrismBridge::Get();
// in case the system was destroyed
if (bridge == nullptr) {
Expand All @@ -150,32 +170,75 @@ RenderTarget* NativeSurface::Acquire(math::Vec2ui size, SurfaceData surfaceData)
}

auto frame = frameManager.CreateFrame(surfaceData, size);
frame->acquireBegin = begin;

LogDebug("Acquire " << frame->ToString() << "(" << size.x << ", " << size.y << ")");

auto mode = TransferModeManager::Instance()->GetTransferMode(surfaceData.transferMode);

LogDebug("Creating it with " << mode->Name());
texturePoolMutex.lock();
// create pool if needed
if (texturePool.find(surfaceData.transferMode) == texturePool.end()) {
auto mode = TransferModeManager::Instance()->GetTransferMode(surfaceData.transferMode);
LogDebug("Creating Shared Texture Pool for surface " << surfaceId << " and mode " << mode->Name());
auto pool = new SharedTexturePool(GetContext(), GetFxContext(), mode);
texturePool[surfaceData.transferMode] = pool;
}
auto pool = texturePool[surfaceData.transferMode];
texturePoolMutex.unlock();

auto tex = pool->AcquireTexture(size);

auto tex = mode->CreateSharedTexture(GetContext(), GetFxContext(), frame);
pool->DisposeUnusedTextures();

// auto mode = TransferModeManager::Instance()->GetTransferMode(surfaceData.transferMode);
//
// LogDebug("Creating it with " << mode->Name());
//
// auto tex = mode->CreateSharedTexture(GetContext(), GetFxContext(), size);
frame->SetSharedTexture(tex);

if (!tex->BeforeRender()) {
LogError("Failed to acquire surface!");
}



frame->acquireEnd = std::chrono::steady_clock::now();
return frame;
}

void NativeSurface::DisposeFrame(long long frameId) {
auto frame = frameManager.GetFrame(frameId);
LogDebug("Frame done. " << frame->TimeReport());
auto texture = frame->GetSharedTexture();
auto transferMode = frame->GetSurfaceData().transferMode;
frame->SetSharedTexture(nullptr);

texturePoolMutex.lock();
if (texturePool.find(transferMode) != texturePool.end()) {
// we only release the frame if the pool is still available
texturePool[transferMode]->ReleaseTexture(texture);
}
else {
// TODO this destroys at least the macos javafx context state
// delete texture;
// for now we leak it..
}
texturePoolMutex.unlock();

frameManager.DisposeFrame(frameId);
}


void NativeSurface::Present(RenderTarget* target, PresentationHint hint) {
auto begin = std::chrono::steady_clock::now();
if (target == nullptr) {
LogDebug("Cannot present nullptr; doing nothing.");
return;
}

auto frame = dynamic_cast<Frame*>(target);
frame->presentBegin = begin;
LogDebug("Present " << frame->ToString());

auto tex = frame->GetSharedTexture();
Expand All @@ -186,7 +249,9 @@ void NativeSurface::Present(RenderTarget* target, PresentationHint hint) {

api->Present(frame);

GetFrameManager()->DisposePendingFrames();
//GetFrameManager()->DisposePendingFrames();

frame->presentEnd = std::chrono::steady_clock::now();
}

driftfx::TransferMode* NativeSurface::GetTransferMode() {
Expand Down
Loading

0 comments on commit c99cccf

Please sign in to comment.