X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=retrace%2Fglretrace_ws.cpp;h=ac03fcc97de6d56390f807a3b1661e6571d489c1;hb=HEAD;hp=bead54ee10ea0566a471604e2a37c423f1eeb181;hpb=9115776479fc67fe12cc3f7ccb8da2fd684d2232;p=apitrace diff --git a/retrace/glretrace_ws.cpp b/retrace/glretrace_ws.cpp index bead54e..ac03fcc 100644 --- a/retrace/glretrace_ws.cpp +++ b/retrace/glretrace_ws.cpp @@ -31,6 +31,7 @@ #include +#include "os_thread.hpp" #include "retrace.hpp" #include "glproc.hpp" #include "glstate.hpp" @@ -40,10 +41,6 @@ namespace glretrace { -glws::Drawable *currentDrawable = NULL; -Context *currentContext = NULL; - - static glws::Visual * visuals[glws::PROFILE_MAX]; @@ -53,6 +50,10 @@ getVisual(glws::Profile profile) { glws::Visual * & visual = visuals[profile]; if (!visual) { visual = glws::createVisual(retrace::doubleBuffer, profile); + if (!visual) { + std::cerr << "error: failed to create OpenGL visual\n"; + exit(1); + } } return visual; } @@ -69,29 +70,42 @@ getDefaultProfile(void) } -glws::Drawable * -createDrawable(glws::Profile profile) { - glws::Drawable *draw = glws::createDrawable(getVisual(profile)); +static glws::Drawable * +createDrawableHelper(glws::Profile profile, int width = 32, int height = 32, bool pbuffer = false) { + glws::Visual *visual = getVisual(profile); + glws::Drawable *draw = glws::createDrawable(visual, width, height, pbuffer); if (!draw) { std::cerr << "error: failed to create OpenGL drawable\n"; exit(1); - return NULL; } return draw; } +glws::Drawable * +createDrawable(glws::Profile profile) { + return createDrawableHelper(profile); +} + + glws::Drawable * createDrawable(void) { - return glretrace::createDrawable(getDefaultProfile()); + return createDrawable(getDefaultProfile()); +} + + +glws::Drawable * +createPbuffer(int width, int height) { + return createDrawableHelper(getDefaultProfile(), width, height, true); } Context * createContext(Context *shareContext, glws::Profile profile) { + glws::Visual *visual = getVisual(profile); glws::Context *shareWsContext = shareContext ? shareContext->wsContext : NULL; - glws::Context *ctx = glws::createContext(getVisual(profile), shareWsContext, profile, retrace::debug); + glws::Context *ctx = glws::createContext(visual, shareWsContext, profile, retrace::debug); if (!ctx) { std::cerr << "error: failed to create OpenGL context\n"; exit(1); @@ -108,14 +122,30 @@ createContext(Context *shareContext) { } +Context::~Context() +{ + //assert(this != getCurrentContext()); + if (this != getCurrentContext()) { + delete wsContext; + } +} + + +static thread_specific Context * +currentContextPtr; + + bool makeCurrent(trace::Call &call, glws::Drawable *drawable, Context *context) { + Context *currentContext = currentContextPtr; + glws::Drawable *currentDrawable = currentContext ? currentContext->drawable : NULL; + if (drawable == currentDrawable && context == currentContext) { return true; } - if (currentDrawable && currentContext) { + if (currentContext) { glFlush(); if (!retrace::doubleBuffer) { frame_complete(call); @@ -132,25 +162,25 @@ makeCurrent(trace::Call &call, glws::Drawable *drawable, Context *context) return false; } - if (context) { + currentContextPtr = context; + + if (drawable && context) { + context->drawable = drawable; + if (!context->used) { initContext(); context->used = true; } } - if (drawable && context) { - currentDrawable = drawable; - currentContext = context; - } else { - currentDrawable = NULL; - currentContext = NULL; - } - return true; } +Context * +getCurrentContext(void) { + return currentContextPtr; +} /** @@ -161,7 +191,15 @@ makeCurrent(trace::Call &call, glws::Drawable *drawable, Context *context) */ void updateDrawable(int width, int height) { - if (!currentDrawable) { + Context *currentContext = getCurrentContext(); + if (!currentContext) { + return; + } + + glws::Drawable *currentDrawable = currentContext->drawable; + assert(currentDrawable); + + if (currentDrawable->pbuffer) { return; } @@ -190,4 +228,26 @@ updateDrawable(int width, int height) { } +int +parseAttrib(const trace::Value *attribs, int param, int default_ = 0) { + const trace::Array *attribs_ = dynamic_cast(attribs); + + if (attribs_) { + for (size_t i = 0; i + 1 < attribs_->values.size(); i += 2) { + int param_i = attribs_->values[i]->toSInt(); + if (param_i == 0) { + break; + } + + if (param_i == param) { + int value = attribs_->values[i + 1]->toSInt(); + return value; + } + } + } + + return default_; +} + + } /* namespace glretrace */