Skip to content

Commit

Permalink
Revised Win32 Frambuffer further and fixed bugs
Browse files Browse the repository at this point in the history
New features:
- Ability to view individual channels (RGBA)
  Hotkeys: C - Color (all of RGB[A])
           R - Red, G - Green, B - Blue, A - Alpha
- Press CTRL-{R,G,B} to toggle those channels on or off
  (can view combination of {R,G,B} channels)
- Pan cursor while dragging.
- Caption bar reflects the channels being viewed.
- HOME key centers the image to window while preserving zoom factor.
- Refactored much code.

Bug fixes:
- Fixed crash while closing framebuffer window due to core renderer unloading
  display driver DLL immediately followed by other threads attempting to access
  its code.
  (We now issue an abort request and unload the module when it's safe to do so).
- Fixed bug in platform-independent part of framebuffer where the Window class
  would be destructed multiple times due to `delete` being called in
 `displayData` function.
- Fixed parts of drawing code to redraw parts of the window correctly.
  • Loading branch information
alexbudgh committed May 19, 2010
1 parent 166c170 commit 1bb31d5
Show file tree
Hide file tree
Showing 9 changed files with 455 additions and 147 deletions.
387 changes: 283 additions & 104 deletions src/framebuffer/fbw.cpp

Large diffs are not rendered by default.

36 changes: 31 additions & 5 deletions src/framebuffer/fbw.h
Expand Up @@ -36,6 +36,13 @@

#include "framebuffer.h"

enum CHANNEL {
CHAN_RED,
CHAN_GREEN,
CHAN_BLUE,
CHAN_ALPHA,
MAX_CHANNELS
};

///////////////////////////////////////////////////////////////////////
// Class : CWinDisplay
Expand All @@ -53,27 +60,42 @@ class CWinDisplay : public CDisplay {
HANDLE thread;

void redraw();
void redraw(HDC hdc, RECT *rcUpdate);
void OnMouseDown(int x, int y);
void OnMouseUp(int x, int y);
void OnMouseMove(int x, int y);
void OnMouseWheel(int x, int y, int zDelta);
void OnKeyDown(int vk);
void OnSize(int cx, int cy);
BOOL OnSetCursor();
void OnGetMinMaxInfo(MINMAXINFO *mmi);
private:
HINSTANCE hInst; // current instance
HWND hWnd; // current window
BITMAPINFO info; // bitmap info
RGBQUAD *bmiColors; // the colors
unsigned int *imageData;

unsigned int *imageData; // Cached, quantized color channel for display.

float *m_channelData[MAX_CHANNELS]; // Original float channel data

// Tells us whether a channel is present.
bool m_channelsPresent[MAX_CHANNELS];

int active;
int willRedraw;

void QuantizeChannels(DWORD channels);
void QuantizeAlpha();
DWORD ComputeDisplayPixel(DWORD channels, int x, int y);

void UpdateWinTitle();
void ZoomImage(float mag); // Zoom to a fixed factor.
void ZoomDelta(float dmag); // Zoom by some offset

void ToggleChannel(int channel);
void ShowAlpha();
void ShowChannel(int channel);
void ShowRGBA();
void SetRGBA();

// Helper functions for common cases.
void ZoomIn();
void ZoomOut();
Expand All @@ -84,12 +106,16 @@ class CWinDisplay : public CDisplay {
Gdiplus::GdiplusStartupInput gdiplusStartupInput;
TCHAR wndTitle[200];

DWORD m_channels;
bool m_alpha; // Show alpha only (takes precedence over color).

// Zoom origin
POINTFLOAT zoomOrigin;
POINTFLOAT lastPos;
float mag_fac;
POINT vpOrigin; // viewport origin.
bool mouseDown;

HCURSOR curPan; // Pan cursor.
};


Expand Down
26 changes: 8 additions & 18 deletions src/framebuffer/framebuffer.cpp
Expand Up @@ -95,7 +95,6 @@ void CDisplay::clampData(int w,int h,float *d) {
// Return Value : The handle to the image on success, NULL othervise
// Comments :
void *displayStart(const char *name,int width,int height,int numSamples,const char *samples,TDisplayParameterFunction findParameter) {

#ifdef _WINDOWS
CWinDisplay *cWindow = new CWinDisplay(name,samples,width,height,numSamples);
#else
Expand All @@ -115,17 +114,13 @@ void *displayStart(const char *name,int width,int height,int numSamples,const ch
// Description : Receive image data
// Return Value : TRUE on success, FALSE otherwise
// Comments :
int displayData(void *im,int x,int y,int w,int h,float *data) {
CDisplay *cWindow = (CDisplay *) im;

assert(cWindow != NULL);
// NOTE: This code needs to be re-entrant, as it will be called from multiple
// threads at the same time!

if (cWindow->data(x,y,w,h,data) == FALSE) {
delete cWindow;
return FALSE;
}

return TRUE;
int displayData(void *im,int x,int y,int w,int h,float *data) {
CDisplay *cWindow = (CDisplay *) im;
return cWindow->data(x,y,w,h,data);
}

///////////////////////////////////////////////////////////////////////
Expand All @@ -134,13 +129,8 @@ int displayData(void *im,int x,int y,int w,int h,float *data) {
// Return Value : TRUE on success, FALSE othervise
// Comments :
void displayFinish(void *im) {
CDisplay *cWindow = (CDisplay *) im;

assert(cWindow != NULL);

cWindow->finish();

delete cWindow;

CDisplay *cWindow = (CDisplay *) im;
cWindow->finish();
delete cWindow;
}

82 changes: 82 additions & 0 deletions src/framebuffer/framebuffer.rc
@@ -0,0 +1,82 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"

#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"

/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS

/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32

#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//

1 TEXTINCLUDE
BEGIN
"resource.h\0"
END

2 TEXTINCLUDE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END

3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END

#endif // APSTUDIO_INVOKED

#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////


/////////////////////////////////////////////////////////////////////////////
// English (Australia) resources

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENA)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_AUS
#pragma code_page(1252)
#endif //_WIN32

/////////////////////////////////////////////////////////////////////////////
//
// Cursor
//

IDC_PAN CURSOR "D:\\dev\\pixie\\src\\framebuffer\\panCursor.cur"
#endif // English (Australia) resources
/////////////////////////////////////////////////////////////////////////////



#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//


/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

Binary file added src/framebuffer/panCursor.cur
Binary file not shown.
16 changes: 16 additions & 0 deletions src/framebuffer/resource.h
@@ -0,0 +1,16 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by framebuffer.rc
//
#define IDC_PAN 101

// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 102
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
4 changes: 3 additions & 1 deletion src/ri/renderer.h
Expand Up @@ -465,10 +465,12 @@ class CRenderer {
class CDisplayData {
public:
CDisplayData(): module(NULL), handle(NULL), start(NULL), data(NULL),
rawData(NULL), finish(NULL), display(NULL) {}
rawData(NULL), finish(NULL), display(NULL), abort(false)
{}

void *module; // The module handle for the out device
void *handle; // The handle for the out device
bool abort; // Is an abort in progress?
int numSamples; // The number of samples
CDisplayChannel *channels;
int numChannels;
Expand Down
41 changes: 23 additions & 18 deletions src/ri/rendererDisplay.cpp
Expand Up @@ -212,13 +212,15 @@ void CRenderer::endDisplays() {
// Finish the out images
for (i=0;i<numDisplays;i++) {

// Is the module up ?
if (datas[i].module != NULL) {
datas[i].finish(datas[i].handle);
if (strcmp(datas[i].display->outDevice,RI_SHADOW) == 0) {
CRenderer::context->RiMakeShadowV(datas[i].displayName,datas[i].displayName,0,NULL,NULL);
}
}
// Call its cleanup function.
datas[i].finish(datas[i].handle);

// Unload it from memory.
osUnloadModule(datas[i].module);

if (strcmp(datas[i].display->outDevice,RI_SHADOW) == 0) {
CRenderer::context->RiMakeShadowV(datas[i].displayName,datas[i].displayName,0,NULL,NULL);
}
if (datas[i].displayName != NULL) free(datas[i].displayName);

// Delete the fill array if set
Expand Down Expand Up @@ -265,7 +267,7 @@ void CRenderer::dispatch(int left,int top,int width,int height,float *pixels) {

// Send the pixels to the output servers
for (i=0;i<numDisplays;i++) {
if (datas[i].module != NULL) {
if (!datas[i].abort) { // Check for abort requested.
float *dispatchData;
int imageSamples = datas[i].numSamples;
int size = width*height*imageSamples*sizeof(float);
Expand All @@ -291,16 +293,19 @@ void CRenderer::dispatch(int left,int top,int width,int height,float *pixels) {
}
}

if (datas[i].data(datas[i].handle,left,top,width,height,dispatchData) == FALSE) {
// Lock this piece of code
osLock(displayKillMutex);
datas[i].handle = NULL;
numActiveDisplays--;
if (numActiveDisplays == 0) hiderFlags |= HIDER_BREAK;
osUnloadModule(datas[i].module);
datas[i].module = NULL;
osUnlock(displayKillMutex);
}
if (datas[i].data(datas[i].handle, left,
top, width, height, dispatchData) == FALSE) {
// Lock this piece of code
osLock(displayKillMutex);
datas[i].abort = true; // Abort was requested.
numActiveDisplays--;
if (numActiveDisplays == 0) hiderFlags |= HIDER_BREAK;
// NOTE: It's not safe to unload the module here, since
// another thread may be about to enter its data() function above!
// We just mark this display as having an abort request and clean it
// up at the end, skipping the rest of the buckets.
osUnlock(displayKillMutex);
}

if (size >= MAX_DISPATCH_SIZE) delete [] dispatchData;
}
Expand Down
10 changes: 9 additions & 1 deletion windows/vcnet8/Pixie/framebuffer/framebuffer.vcproj
Expand Up @@ -408,7 +408,7 @@
>
</File>
<File
RelativePath=".\resource.h"
RelativePath="..\..\..\..\src\framebuffer\resource.h"
>
</File>
</Filter>
Expand All @@ -417,6 +417,14 @@
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
<File
RelativePath="..\..\..\..\src\framebuffer\framebuffer.rc"
>
</File>
<File
RelativePath="..\..\..\..\src\framebuffer\panCursor.cur"
>
</File>
</Filter>
</Files>
<Globals>
Expand Down

0 comments on commit 1bb31d5

Please sign in to comment.