Skip to content

Commit

Permalink
Cleanup|Refactor: Cleaned up the GL deferred tasks module
Browse files Browse the repository at this point in the history
Getting it ready for deferred GL API calls.
  • Loading branch information
skyjake committed Feb 7, 2012
1 parent 6f591a6 commit 8244c9e
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 76 deletions.
87 changes: 47 additions & 40 deletions doomsday/engine/portable/include/gl_defer.h
@@ -1,66 +1,73 @@
/**\file gl_defer.h
*\section License
* License: GPL
* Online License Link: http://www.gnu.org/licenses/gpl.html
/**
* @file gl_defer.h
* Deferred GL tasks. @ingroup gl
*
*\author Copyright © 2003-2012 Jaakko Keränen <jaakko.keranen@iki.fi>
*\author Copyright © 2006-2012 Daniel Swanson <danij@dengine.net>
* GL is only available from the main thread. When accessed from other threads,
* the operations need to be deferred for processing later in the main thread.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* @authors Copyright © 2003-2012 Jaakko Keränen <jaakko.keranen@iki.fi>
* @authors Copyright © 2006-2012 Daniel Swanson <danij@dengine.net>
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* @par License
* GPL: http://www.gnu.org/licenses/gpl.html
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/

/**
* Deferred GL Tasks.
* <small>This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. This program is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details. You should have received a copy of the GNU
* General Public License along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA</small>
*/

#ifndef LIBDENG_GL_DEFERRED_H
#define LIBDENG_GL_DEFERRED_H

typedef enum {
DEFERREDTASK_TYPES_FIRST = 0,
DTT_UPLOAD_TEXTURECONTENT = DEFERREDTASK_TYPES_FIRST,
DEFERREDTASK_TYPES_COUNT
} deferredtask_type_t;
struct texturecontent_s;

#define VALID_DEFERREDTASK_TYPE(t) ((t) >= DEFERREDTASK_TYPES_FIRST || (t) < DEFERREDTASK_TYPES_COUNT)

/// Initialize this module.
/**
* Initializes the deferred tasks module.
*/
void GL_InitDeferredTask(void);

/// Shutdown this module.
/**
* Shuts down the deferred tasks.
*/
void GL_ShutdownDeferredTask(void);

/// @return Number of waiting tasks else @c 0
int GL_DeferredTaskCount(void);

/**
* @param timeOutMilliSeconds Zero for no timeout.
* Clears the currently queued GL tasks. They will not be executed.
*/
void GL_ProcessDeferredTasks(uint timeOutMilliSeconds);

void GL_PurgeDeferredTasks(void);

/**
* @param type Type of task to add.
* @param data Caller-supplied additional data ptr, linked with the task.
* @return Number of GL tasks waiting to be carried out.
*/
void GL_EnqueueDeferredTask(deferredtask_type_t type, void* data);
int GL_DeferredTaskCount(void);

/**
* Processes deferred GL tasks. This must be called from the main thread.
*
* @param timeOutMilliSeconds Processing will continue until this timeout expires.
* Use zero for no timeout.
*/
void GL_ProcessDeferredTasks(uint timeOutMilliSeconds);

DGLuint GL_GetReservedTextureName(void);

void GL_ReserveNames(void);

void GL_ReleaseReservedNames(void);

/**
* Adds a new deferred texture upload task to the queue.
*
* @param content Texture content to upload. Caller can free its copy of the content;
* a copy is made for the deferred task.
*/
void GL_DeferTextureUpload(const struct texturecontent_s* content);

#endif /* LIBDENG_GL_DEFERRED_H */
86 changes: 52 additions & 34 deletions doomsday/engine/portable/src/gl_defer.c
@@ -1,29 +1,23 @@
/**\file gl_defer.c
*\section License
* License: GPL
* Online License Link: http://www.gnu.org/licenses/gpl.html
*
*\author Copyright © 2003-2012 Jaakko Keränen <jaakko.keranen@iki.fi>
*\author Copyright © 2005-2012 Daniel Swanson <danij@dengine.net>
/**
* @file gl_defer.c
* Implementation of deferred GL tasks. @ingroup gl
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* @authors Copyright © 2003-2012 Jaakko Keränen <jaakko.keranen@iki.fi>
* @authors Copyright © 2005-2012 Daniel Swanson <danij@dengine.net>
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* @par License
* GPL: http://www.gnu.org/licenses/gpl.html
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/

/**
* Deferred GL Tasks.
* <small>This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. This program is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details. You should have received a copy of the GNU
* General Public License along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA</small>
*/

#ifdef UNIX
Expand All @@ -39,6 +33,14 @@

#define NUM_RESERVED_TEXTURENAMES 512

typedef enum {
DEFERREDTASK_TYPES_FIRST = 0,
DTT_UPLOAD_TEXTURECONTENT = DEFERREDTASK_TYPES_FIRST,
DEFERREDTASK_TYPES_COUNT
} deferredtask_type_t;

#define VALID_DEFERREDTASK_TYPE(t) ((t) >= DEFERREDTASK_TYPES_FIRST || (t) < DEFERREDTASK_TYPES_COUNT)

typedef struct deferredtask_s {
struct deferredtask_s* next;
deferredtask_type_t type;
Expand Down Expand Up @@ -214,7 +216,7 @@ void GL_PurgeDeferredTasks(void)
Sys_Unlock(deferredMutex);
}

void GL_EnqueueDeferredTask(deferredtask_type_t type, void* data)
static void GL_AddDeferredTask(deferredtask_type_t type, void* data)
{
deferredtask_t* d;

Expand All @@ -231,7 +233,13 @@ void GL_EnqueueDeferredTask(deferredtask_type_t type, void* data)
Sys_Unlock(deferredMutex);
}

deferredtask_t* GL_NextDeferredTask(void)
void GL_DeferTextureUpload(const struct texturecontent_s* content)
{
// Defer this operation. Need to make a copy.
GL_AddDeferredTask(DTT_UPLOAD_TEXTURECONTENT, GL_ConstructTextureContentCopy(content));
}

static deferredtask_t* GL_NextDeferredTask(void)
{
deferredtask_t* d = NULL;
if(!inited)
Expand All @@ -242,6 +250,20 @@ deferredtask_t* GL_NextDeferredTask(void)
return d;
}

static void processDeferredTask(deferredtask_t* task)
{
switch(task->type)
{
case DTT_UPLOAD_TEXTURECONTENT:
GL_UploadTextureContent(task->data);
break;

default:
Con_Error("Unknown deferred GL task type %i.", (int) task->type);
break;
}
}

void GL_ProcessDeferredTasks(uint timeOutMilliSeconds)
{
deferredtask_t* d;
Expand All @@ -250,26 +272,22 @@ void GL_ProcessDeferredTasks(uint timeOutMilliSeconds)
if(!inited)
Con_Error("GL_ProcessDeferredTasks: Deferred GL task system not initialized.");

LIBDENG_ASSERT_IN_MAIN_THREAD();

startTime = Sys_GetRealTime();

// We'll reserve names multiple times, because the worker thread may be
// needing new texture names while we are uploading.
GL_ReserveNames();

while((!timeOutMilliSeconds ||
Sys_GetRealTime() - startTime < timeOutMilliSeconds) &&
(d = GL_NextDeferredTask()) != NULL)
{
switch(d->type)
{
case DTT_UPLOAD_TEXTURECONTENT:
GL_UploadTextureContent(d->data);
break;
default:
Con_Error("GL_ProcessDeferredTasks: Unknown task type %i.", (int) d->type);
break; // Unreachable.
}
processDeferredTask(d);
destroyDeferredTask(d);
GL_ReserveNames();
}

GL_ReserveNames();
}
3 changes: 1 addition & 2 deletions doomsday/engine/portable/src/gl_texmanager.c
Expand Up @@ -660,8 +660,7 @@ static void uploadContent(uploadcontentmethod_t uploadMethod, const textureconte
GL_UploadTextureContent(content);
return;
}
// Defer this operation. Need to make a copy.
GL_EnqueueDeferredTask(DTT_UPLOAD_TEXTURECONTENT, GL_ConstructTextureContentCopy(content));
GL_DeferTextureUpload(content);
}

static uploadcontentmethod_t uploadContentForVariant(uploadcontentmethod_t uploadMethod,
Expand Down

0 comments on commit 8244c9e

Please sign in to comment.