* honors new frame size in the LockGL() method of the renderer, FrameResized() now notifies the renderer.

* checks whether the rendered bitmap size matches the direct info size, if not, the renderer doesn't draw.
* we don't lock the view looper anymore in LockGL(), this avoids deadlocks with FrameResized().
* lock drawing when modifying the direct connection info.
* the renderer now locks the view looper with a timeout, as on resize the looper is locked and FrameResized called.
* the bug #3027 is fixed.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30472 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Jérôme Duval
2009-04-27 20:28:11 +00:00
parent 9c08ace28c
commit dc4c7cc492
3 changed files with 160 additions and 116 deletions
@@ -297,6 +297,12 @@ MesaSoftwareRenderer::MesaSoftwareRenderer(BGLView* view, ulong options,
_mesa_enable_1_3_extensions(fContext);
_mesa_enable_1_4_extensions(fContext);
_mesa_enable_1_5_extensions(fContext);
_mesa_enable_2_0_extensions(fContext);
_mesa_enable_2_1_extensions(fContext);
BRect bounds = view->Bounds();
fWidth = fNewWidth = (GLint)bounds.Width();
fHeight = fNewHeight = (GLint)bounds.Height();
// some stupid applications (Quake2) don't even think about calling LockGL()
// before using glGetString and its glGet*() friends...
@@ -326,17 +332,24 @@ MesaSoftwareRenderer::LockGL()
_mesa_make_current(fContext, fFrameBuffer, fFrameBuffer);
BRect b = GLView()->Bounds();
color_space cs = B_RGBA32;
BAutolock lock(fInfoLocker);
if (fDirectModeEnabled && fInfo != NULL) {
cs = BScreen(GLView()->Window()).ColorSpace();
fNewWidth = fInfo->window_bounds.right
- fInfo->window_bounds.left + 1;
fNewHeight = fInfo->window_bounds.bottom
- fInfo->window_bounds.top + 1;
}
uint32 width = b.IntegerWidth() + 1;
uint32 height = b.IntegerHeight() + 1;
if (width != fWidth || height != fHeight || !fBitmap || cs != fColorSpace) {
if (fBitmap && cs == fColorSpace && fNewWidth == fWidth
&& fNewHeight == fHeight)
return;
if (cs != fColorSpace) {
switch (cs) {
fColorSpace = cs;
switch (fColorSpace) {
case B_RGBA32:
fRenderBuffer->GetRow = get_row_RGBA32;
fRenderBuffer->GetValues = get_values_RGBA32;
@@ -392,27 +405,16 @@ MesaSoftwareRenderer::LockGL()
fRenderBuffer->PutMonoValues = put_mono_values_CMAP8;
break;
default:
fprintf(stderr, "unsupported screen color space %d\n", cs);
fprintf(stderr, "unsupported screen color space %d\n", fColorSpace);
debugger("unsupported OpenGL color space");
break;
}
}
// allocate new size of back buffer bitmap
delete fBitmap;
fColorSpace = cs;
BRect rect(0.0, 0.0, width - 1, height - 1);
fBitmap = new BBitmap(rect, fColorSpace);
for (uint i = 0; i < height; i++) {
fRowAddr[height - i - 1] = (GLvoid *)((GLubyte *)fBitmap->Bits()
+ i * fBitmap->BytesPerRow());
}
fWidth = fNewWidth;
fHeight = fNewHeight;
_mesa_resize_framebuffer(fContext, fFrameBuffer, width, height);
fWidth = width;
fHeight = height;
fRenderBuffer->Data = fBitmap->Bits();
}
_AllocateBitmap();
}
@@ -435,16 +437,27 @@ MesaSoftwareRenderer::SwapBuffers(bool VSync)
// TODO: support VSync
if (fBitmap) {
if (!fBitmap)
return;
if (fVisual->doubleBufferMode)
_mesa_notifySwapBuffers(fContext);
if (!fDirectModeEnabled || fInfo == NULL) {
GLView()->LockLooper();
if (GLView()->LockLooperWithTimeout(1000) == B_OK) {
GLView()->DrawBitmap(fBitmap);
GLView()->UnlockLooper();
} else {
}
return;
}
BAutolock lock(fInfoLocker);
// check the bitmap size still matches the size
if (fInfo->window_bounds.bottom - fInfo->window_bounds.top
!= fBitmap->Bounds().IntegerHeight()
|| fInfo->window_bounds.right - fInfo->window_bounds.left
!= fBitmap->Bounds().IntegerWidth())
return;
uint8 bytesPerPixel = fInfo->bits_per_pixel / 8;
uint32 bytesPerRow = fBitmap->BytesPerRow();
for (uint32 i = 0; i < fInfo->clip_list_count; i++) {
@@ -456,7 +469,8 @@ MesaSoftwareRenderer::SwapBuffers(bool VSync)
* fInfo->bytes_per_row + clip->left * bytesPerPixel;
uint8 *b = (uint8 *)fBitmap->Bits()
+ (clip->top - fInfo->window_bounds.top) * bytesPerRow
+ (clip->left - fInfo->window_bounds.left) * bytesPerPixel;
+ (clip->left - fInfo->window_bounds.left)
* bytesPerPixel;
for (int y = 0; y < height; y++) {
memcpy(p, b, bytesWidth);
@@ -465,8 +479,6 @@ MesaSoftwareRenderer::SwapBuffers(bool VSync)
}
}
}
}
}
void
@@ -579,6 +591,32 @@ MesaSoftwareRenderer::DirectConnected(direct_buffer_info *info)
}
void
MesaSoftwareRenderer::FrameResized(float width, float height)
{
BAutolock lock(fInfoLocker);
fNewWidth = (GLuint)width;
fNewHeight = (GLuint)height;
}
void
MesaSoftwareRenderer::_AllocateBitmap()
{
// allocate new size of back buffer bitmap
delete fBitmap;
BRect rect(0.0, 0.0, fWidth - 1, fHeight - 1);
fBitmap = new BBitmap(rect, fColorSpace);
for (uint i = 0; i < fHeight; i++) {
fRowAddr[fHeight - i - 1] = (GLvoid *)((GLubyte *)fBitmap->Bits()
+ i * fBitmap->BytesPerRow());
}
_mesa_resize_framebuffer(fContext, fFrameBuffer, fWidth, fHeight);
fRenderBuffer->Data = fBitmap->Bits();
}
// #pragma mark - static
@@ -37,6 +37,7 @@ public:
virtual void Draw(BRect updateRect);
virtual status_t CopyPixelsOut(BPoint source, BBitmap* dest);
virtual status_t CopyPixelsIn(BBitmap* source, BPoint dest);
virtual void FrameResized(float width, float height);
GLvoid** GetRows() { return fRowAddr; }
@@ -60,6 +61,8 @@ private:
GLuint width, GLuint height);
static void Flush(GLcontext *ctx);
void _AllocateBitmap();
BBitmap* fBitmap;
bool fDirectModeEnabled;
direct_buffer_info* fInfo;
@@ -73,8 +76,8 @@ private:
GLchan fClearColor[4]; // buffer clear color
GLuint fClearIndex; // buffer clear color index
GLuint fWidth;
GLuint fHeight;
GLuint fWidth, fNewWidth;
GLuint fHeight, fNewHeight;
color_space fColorSpace;
GLvoid* fRowAddr[MAX_HEIGHT];
+10 -7
View File
@@ -84,8 +84,6 @@ BGLView::LockGL()
{
// TODO: acquire the OpenGL API lock it on this glview
if (!LockLooper())
return;
fDisplayLock.Lock();
if (fRenderer)
fRenderer->LockGL();
@@ -95,12 +93,9 @@ BGLView::LockGL()
void
BGLView::UnlockGL()
{
if (!fDisplayLock.IsLocked())
return;
fDisplayLock.Unlock();
if (fRenderer)
fRenderer->UnlockGL();
UnlockLooper();
fDisplayLock.Unlock();
// TODO: release the GL API lock to others glviews
}
@@ -211,6 +206,7 @@ BGLView::AttachedToWindow()
#endif
// Set default OpenGL viewport:
glViewport(0, 0, Bounds().IntegerWidth(), Bounds().IntegerHeight());
fRenderer->FrameResized(Bounds().IntegerWidth(), Bounds().IntegerHeight());
if (fClipInfo) {
fRenderer->DirectConnected(
@@ -263,8 +259,13 @@ BGLView::FrameResized(float width, float height)
for (BView *v = this; v; v = v->Parent())
v->ConvertToParent(&fBounds);
if (fRenderer)
if (fRenderer) {
LockGL();
_LockDraw();
fRenderer->FrameResized(width, height);
_UnlockDraw();
UnlockGL();
}
BView::FrameResized(width, height);
}
@@ -344,6 +345,7 @@ BGLView::DirectConnected(direct_buffer_info *info)
_UnlockDraw();
case B_DIRECT_MODIFY:
{
_LockDraw();
localInfo->buffer_state = info->buffer_state;
localInfo->driver_state = info->driver_state;
localInfo->bits = info->bits;
@@ -371,6 +373,7 @@ BGLView::DirectConnected(direct_buffer_info *info)
for (uint32 c = 0; c < localInfo->clip_list_count; c++)
localInfo->clip_list[c] = region.RectAtInt(c);
_UnlockDraw();
break;
}
case B_DIRECT_STOP: