code refactoring, moved common stuff into the base class
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@12129 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -42,9 +42,11 @@
|
|||||||
#include "Workspace.h"
|
#include "Workspace.h"
|
||||||
|
|
||||||
#include "AccelerantDriver.h"
|
#include "AccelerantDriver.h"
|
||||||
#include "ViewDriver.h"
|
#ifndef __HAIKU__
|
||||||
#include "DirectDriver.h"
|
#include "ViewDriver.h"
|
||||||
#include "DisplayDriverPainter.h"
|
#include "DirectDriver.h"
|
||||||
|
#include "DisplayDriverPainter.h"
|
||||||
|
#endif // __HAIKU__
|
||||||
|
|
||||||
//#define DEBUG_DESKTOP
|
//#define DEBUG_DESKTOP
|
||||||
|
|
||||||
@@ -125,7 +127,8 @@ Desktop::AddDriver(DisplayDriver *driver)
|
|||||||
{
|
{
|
||||||
if (driver->Initialize()) {
|
if (driver->Initialize()) {
|
||||||
// TODO: be careful of screen initialization - monitor may not support 640x480
|
// TODO: be careful of screen initialization - monitor may not support 640x480
|
||||||
Screen *sc = new Screen(driver, BPoint(640, 480), B_RGB32, fScreenList.CountItems()+1);
|
// Screen *sc = new Screen(driver, BPoint(640, 480), B_RGB32, fScreenList.CountItems()+1);
|
||||||
|
Screen *sc = new Screen(driver, BPoint(1024, 768), B_RGB32, fScreenList.CountItems()+1);
|
||||||
// Screen *sc = new Screen(driver, BPoint(640, 480), B_CMAP8, fScreenList.CountItems()+1);
|
// Screen *sc = new Screen(driver, BPoint(640, 480), B_CMAP8, fScreenList.CountItems()+1);
|
||||||
// Screen *sc = new Screen(driver, BPoint(640, 480), B_GRAY8, fScreenList.CountItems()+1);
|
// Screen *sc = new Screen(driver, BPoint(640, 480), B_GRAY8, fScreenList.CountItems()+1);
|
||||||
// Screen *sc = new Screen(driver, BPoint(640, 480), B_RGB15, fScreenList.CountItems()+1);
|
// Screen *sc = new Screen(driver, BPoint(640, 480), B_RGB15, fScreenList.CountItems()+1);
|
||||||
|
|||||||
@@ -94,17 +94,11 @@ AccelerantHWInterface::AccelerantHWInterface()
|
|||||||
fModeList(NULL),
|
fModeList(NULL),
|
||||||
|
|
||||||
fBackBuffer(NULL),
|
fBackBuffer(NULL),
|
||||||
fFrontBuffer(NULL),
|
fFrontBuffer(new AccelerantBuffer())
|
||||||
fUpdateExecutor(new UpdateQueue(this))
|
|
||||||
{
|
{
|
||||||
fDisplayMode.virtual_width = 640;
|
fDisplayMode.virtual_width = 640;
|
||||||
fDisplayMode.virtual_height = 480;
|
fDisplayMode.virtual_height = 480;
|
||||||
fDisplayMode.space = B_RGB32;
|
fDisplayMode.space = B_RGB32;
|
||||||
|
|
||||||
fFrontBuffer = new AccelerantBuffer();
|
|
||||||
|
|
||||||
// TODO: isn't this supposed to be called form outside?
|
|
||||||
Initialize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// destructor
|
// destructor
|
||||||
@@ -522,62 +516,12 @@ AccelerantHWInterface::BackBuffer() const
|
|||||||
return fBackBuffer;
|
return fBackBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Invalidate
|
|
||||||
status_t
|
|
||||||
AccelerantHWInterface::Invalidate(const BRect& frame)
|
|
||||||
{
|
|
||||||
return CopyBackToFront(frame);;
|
|
||||||
|
|
||||||
// TODO: get this working, the locking in the DisplayDriverPainter needs
|
|
||||||
// to be based on locking this object, which essentially means the access
|
|
||||||
// to the back buffer is locked, or more precise the access to the invalid
|
|
||||||
// region scheduled to be copied to the front buffer
|
|
||||||
//fUpdateExecutor->AddRect(frame);
|
|
||||||
//return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// CopyBackToFront
|
|
||||||
status_t
|
|
||||||
AccelerantHWInterface::CopyBackToFront(const BRect &frame)
|
|
||||||
{
|
|
||||||
if (!fBackBuffer || !fFrontBuffer)
|
|
||||||
return B_NO_INIT;
|
|
||||||
|
|
||||||
// we need to mess with the area, but it is const
|
|
||||||
BRect area(frame);
|
|
||||||
|
|
||||||
if (area.IsValid() && area.Intersects(fBackBuffer->Bitmap()->Bounds())) {
|
|
||||||
const BBitmap *from = fBackBuffer->Bitmap();
|
|
||||||
|
|
||||||
// make sure we don't copy out of bounds
|
|
||||||
area = from->Bounds() & area;
|
|
||||||
|
|
||||||
uint32 src_bytes = fBackBuffer->BytesPerRow();
|
|
||||||
uint8 *src_bits = (uint8 *)fBackBuffer->Bits();
|
|
||||||
|
|
||||||
// convert to integer coordinates
|
|
||||||
int32 x = (int32)floorf(area.left);
|
|
||||||
int32 y = (int32)floorf(area.top);
|
|
||||||
int32 right = (int32)ceilf(area.right);
|
|
||||||
int32 bottom = (int32)ceilf(area.bottom);
|
|
||||||
|
|
||||||
// offset to left top pixel in source buffer (always B_RGBA32)
|
|
||||||
src_bits += y * src_bytes + x * 4;
|
|
||||||
|
|
||||||
_CopyToFront(src_bits, src_bytes, x, y, right, bottom);
|
|
||||||
//_DrawCursor(area);
|
|
||||||
|
|
||||||
// update the region on screen
|
|
||||||
//Invalidate(area);
|
|
||||||
}
|
|
||||||
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// _DrawCursor
|
// _DrawCursor
|
||||||
void
|
void
|
||||||
AccelerantHWInterface::_DrawCursor(BRect area) const
|
AccelerantHWInterface::_DrawCursor(BRect area) const
|
||||||
{
|
{
|
||||||
|
return;
|
||||||
|
#if 0
|
||||||
BRect cf = _CursorFrame();
|
BRect cf = _CursorFrame();
|
||||||
if (cf.IsValid() && area.Intersects(cf)) {
|
if (cf.IsValid() && area.Intersects(cf)) {
|
||||||
// clip to common area
|
// clip to common area
|
||||||
@@ -639,161 +583,9 @@ AccelerantHWInterface::_DrawCursor(BRect area) const
|
|||||||
|
|
||||||
delete[] buffer;
|
delete[] buffer;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// _CopyToFront
|
|
||||||
//
|
|
||||||
// * source is assumed to be already at the right offset
|
|
||||||
// * source is assumed to be in B_RGBA32 format
|
|
||||||
// * location in front buffer is calculated
|
|
||||||
// * conversion from B_RGBA32 to format of front buffer is taken care of
|
|
||||||
void
|
|
||||||
AccelerantHWInterface::_CopyToFront(uint8* src, uint32 srcBPR,
|
|
||||||
int32 x, int32 y,
|
|
||||||
int32 right, int32 bottom) const
|
|
||||||
{
|
|
||||||
uint8* dst = (uint8*)fFrontBuffer->Bits();
|
|
||||||
uint32 dstBPR = fFrontBuffer->BytesPerRow();
|
|
||||||
|
|
||||||
// transfer, handle colorspace conversion
|
|
||||||
switch (fFrontBuffer->ColorSpace()) {
|
|
||||||
case B_RGB32:
|
|
||||||
case B_RGBA32: {
|
|
||||||
int32 bytes = (right - x + 1) * 4;
|
|
||||||
|
|
||||||
if (bytes > 0) {
|
|
||||||
// offset to left top pixel in dest buffer
|
|
||||||
dst += y * dstBPR + x * 4;
|
|
||||||
// copy
|
|
||||||
for (; y <= bottom; y++) {
|
|
||||||
memcpy(dst, src, bytes);
|
|
||||||
dst += dstBPR;
|
|
||||||
src += srcBPR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// NOTE: on R5, B_RGB24 bitmaps are not supported by DrawBitmap()
|
|
||||||
case B_RGB24: {
|
|
||||||
// offset to left top pixel in dest buffer
|
|
||||||
dst += y * dstBPR + x * 3;
|
|
||||||
int32 left = x;
|
|
||||||
// copy
|
|
||||||
for (; y <= bottom; y++) {
|
|
||||||
uint8* srcHandle = src;
|
|
||||||
uint8* dstHandle = dst;
|
|
||||||
x = left;
|
|
||||||
for (; x <= right; x++) {
|
|
||||||
dstHandle[0] = srcHandle[0];
|
|
||||||
dstHandle[1] = srcHandle[1];
|
|
||||||
dstHandle[2] = srcHandle[2];
|
|
||||||
dstHandle += 3;
|
|
||||||
srcHandle += 4;
|
|
||||||
}
|
|
||||||
dst += dstBPR;
|
|
||||||
src += srcBPR;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case B_RGB16: {
|
|
||||||
// offset to left top pixel in dest buffer
|
|
||||||
dst += y * dstBPR + x * 2;
|
|
||||||
int32 left = x;
|
|
||||||
// copy
|
|
||||||
// TODO: assumes BGR order, does this work on big endian as well?
|
|
||||||
for (; y <= bottom; y++) {
|
|
||||||
uint8* srcHandle = src;
|
|
||||||
uint16* dstHandle = (uint16*)dst;
|
|
||||||
x = left;
|
|
||||||
for (; x <= right; x++) {
|
|
||||||
*dstHandle = (uint16)(((srcHandle[2] & 0xf8) << 8) |
|
|
||||||
((srcHandle[1] & 0xfc) << 3) |
|
|
||||||
(srcHandle[0] >> 3));
|
|
||||||
dstHandle ++;
|
|
||||||
srcHandle += 4;
|
|
||||||
}
|
|
||||||
dst += dstBPR;
|
|
||||||
src += srcBPR;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case B_RGB15: {
|
|
||||||
// offset to left top pixel in dest buffer
|
|
||||||
dst += y * dstBPR + x * 2;
|
|
||||||
int32 left = x;
|
|
||||||
// copy
|
|
||||||
// TODO: assumes BGR order, does this work on big endian as well?
|
|
||||||
for (; y <= bottom; y++) {
|
|
||||||
uint8* srcHandle = src;
|
|
||||||
uint16* dstHandle = (uint16*)dst;
|
|
||||||
x = left;
|
|
||||||
for (; x <= right; x++) {
|
|
||||||
*dstHandle = (uint16)(((srcHandle[2] & 0xf8) << 7) |
|
|
||||||
((srcHandle[1] & 0xf8) << 2) |
|
|
||||||
(srcHandle[0] >> 3));
|
|
||||||
dstHandle ++;
|
|
||||||
srcHandle += 4;
|
|
||||||
}
|
|
||||||
dst += dstBPR;
|
|
||||||
src += srcBPR;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case B_CMAP8: {
|
|
||||||
// offset to left top pixel in dest buffer
|
|
||||||
dst += y * dstBPR + x;
|
|
||||||
int32 left = x;
|
|
||||||
// copy
|
|
||||||
// TODO: using BScreen will not be an option in the
|
|
||||||
// final implementation, will it? The BBitmap implementation
|
|
||||||
// has a class that handles this, something so useful
|
|
||||||
// should be moved to a more public place.
|
|
||||||
// TODO: assumes BGR order again
|
|
||||||
BScreen screen;
|
|
||||||
for (; y <= bottom; y++) {
|
|
||||||
uint8* srcHandle = src;
|
|
||||||
uint8* dstHandle = dst;
|
|
||||||
x = left;
|
|
||||||
for (; x <= right; x++) {
|
|
||||||
*dstHandle = screen.IndexForColor(srcHandle[2],
|
|
||||||
srcHandle[1],
|
|
||||||
srcHandle[0]);
|
|
||||||
dstHandle ++;
|
|
||||||
srcHandle += 4;
|
|
||||||
}
|
|
||||||
dst += dstBPR;
|
|
||||||
src += srcBPR;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case B_GRAY8: {
|
|
||||||
// offset to left top pixel in dest buffer
|
|
||||||
dst += y * dstBPR + x;
|
|
||||||
int32 left = x;
|
|
||||||
// copy
|
|
||||||
// TODO: assumes BGR order, does this work on big endian as well?
|
|
||||||
for (; y <= bottom; y++) {
|
|
||||||
uint8* srcHandle = src;
|
|
||||||
uint8* dstHandle = dst;
|
|
||||||
x = left;
|
|
||||||
for (; x <= right; x++) {
|
|
||||||
*dstHandle = (308 * srcHandle[2] + 600 * srcHandle[1] + 116 * srcHandle[0]) / 1024;
|
|
||||||
dstHandle ++;
|
|
||||||
srcHandle += 4;
|
|
||||||
}
|
|
||||||
dst += dstBPR;
|
|
||||||
src += srcBPR;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
fprintf(stderr, "AccelerantHWInterface::CopyBackToFront() - unsupported front buffer format!\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*void AccelerantHWInterface::CopyBitmap(ServerBitmap *bitmap, const BRect &source, const BRect &dest, const DrawData *d)
|
/*void AccelerantHWInterface::CopyBitmap(ServerBitmap *bitmap, const BRect &source, const BRect &dest, const DrawData *d)
|
||||||
{
|
{
|
||||||
if(!is_initialized || !bitmap || !d)
|
if(!is_initialized || !bitmap || !d)
|
||||||
|
|||||||
@@ -53,8 +53,8 @@ virtual uint32 DPMSCapabilities() const;
|
|||||||
virtual RenderingBuffer *FrontBuffer() const;
|
virtual RenderingBuffer *FrontBuffer() const;
|
||||||
virtual RenderingBuffer *BackBuffer() const;
|
virtual RenderingBuffer *BackBuffer() const;
|
||||||
|
|
||||||
virtual status_t Invalidate(const BRect& frame);
|
protected:
|
||||||
virtual status_t CopyBackToFront(const BRect& area);
|
virtual void _DrawCursor(BRect area) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int OpenGraphicsDevice(int deviceNumber);
|
int OpenGraphicsDevice(int deviceNumber);
|
||||||
@@ -62,11 +62,6 @@ private:
|
|||||||
status_t UpdateModeList();
|
status_t UpdateModeList();
|
||||||
status_t UpdateFrameBufferConfig();
|
status_t UpdateFrameBufferConfig();
|
||||||
|
|
||||||
void _DrawCursor(BRect area) const;
|
|
||||||
void _CopyToFront(uint8* src, uint32 srcBPR,
|
|
||||||
int32 x, int32 y,
|
|
||||||
int32 right, int32 bottom) const;
|
|
||||||
|
|
||||||
int fCardFD;
|
int fCardFD;
|
||||||
image_id fAccelerantImage;
|
image_id fAccelerantImage;
|
||||||
GetAccelerantHook fAccelerantHook;
|
GetAccelerantHook fAccelerantHook;
|
||||||
|
|||||||
@@ -55,7 +55,13 @@ DisplayDriverPainter::~DisplayDriverPainter()
|
|||||||
bool
|
bool
|
||||||
DisplayDriverPainter::Initialize()
|
DisplayDriverPainter::Initialize()
|
||||||
{
|
{
|
||||||
return DisplayDriver::Initialize();
|
if (DisplayDriver::Initialize()) {
|
||||||
|
status_t err = fGraphicsCard->Initialize();
|
||||||
|
if (err < B_OK)
|
||||||
|
fprintf(stderr, "HWInterface::Initialize() failed: %s\n", strerror(err));
|
||||||
|
return err >= B_OK;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shutdown
|
// Shutdown
|
||||||
|
|||||||
@@ -1,6 +1,15 @@
|
|||||||
// HWInterface.cpp
|
// HWInterface.cpp
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifndef __HAIKU__
|
||||||
|
#include <Screen.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "RenderingBuffer.h"
|
||||||
#include "ServerCursor.h"
|
#include "ServerCursor.h"
|
||||||
|
#include "UpdateQueue.h"
|
||||||
|
|
||||||
#include "HWInterface.h"
|
#include "HWInterface.h"
|
||||||
|
|
||||||
@@ -9,7 +18,8 @@ HWInterface::HWInterface()
|
|||||||
: BLocker("hw interface lock"),
|
: BLocker("hw interface lock"),
|
||||||
fCursor(NULL),
|
fCursor(NULL),
|
||||||
fCursorVisible(true),
|
fCursorVisible(true),
|
||||||
fCursorLocation(0.5, 0.5)
|
fCursorLocation(0.5, 0.5),
|
||||||
|
fUpdateExecutor(new UpdateQueue(this))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -17,6 +27,7 @@ HWInterface::HWInterface()
|
|||||||
HWInterface::~HWInterface()
|
HWInterface::~HWInterface()
|
||||||
{
|
{
|
||||||
delete fCursor;
|
delete fCursor;
|
||||||
|
delete fUpdateExecutor;
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetCursor
|
// SetCursor
|
||||||
@@ -88,6 +99,212 @@ HWInterface::GetCursorPosition()
|
|||||||
return location;
|
return location;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Invalidate
|
||||||
|
status_t
|
||||||
|
HWInterface::Invalidate(const BRect& frame)
|
||||||
|
{
|
||||||
|
return CopyBackToFront(frame);;
|
||||||
|
|
||||||
|
// TODO: get this working, the locking in the DisplayDriverPainter needs
|
||||||
|
// to be based on locking this object, which essentially means the access
|
||||||
|
// to the back buffer is locked, or more precise the access to the invalid
|
||||||
|
// region scheduled to be copied to the front buffer
|
||||||
|
// fUpdateExecutor->AddRect(frame);
|
||||||
|
// return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyBackToFront
|
||||||
|
// * the object must already be locked!
|
||||||
|
status_t
|
||||||
|
HWInterface::CopyBackToFront(const BRect& frame)
|
||||||
|
{
|
||||||
|
RenderingBuffer* frontBuffer = FrontBuffer();
|
||||||
|
RenderingBuffer* backBuffer = BackBuffer();
|
||||||
|
|
||||||
|
if (!backBuffer || !frontBuffer)
|
||||||
|
return B_NO_INIT;
|
||||||
|
|
||||||
|
// we need to mess with the area, but it is const
|
||||||
|
BRect area(frame);
|
||||||
|
BRect bufferClip(0.0, 0.0, backBuffer->Width() - 1, backBuffer->Height() - 1);
|
||||||
|
|
||||||
|
if (area.IsValid() && area.Intersects(bufferClip)) {
|
||||||
|
|
||||||
|
// make sure we don't copy out of bounds
|
||||||
|
area = bufferClip & area;
|
||||||
|
|
||||||
|
uint32 srcBPR = backBuffer->BytesPerRow();
|
||||||
|
uint8* src = (uint8*)backBuffer->Bits();
|
||||||
|
|
||||||
|
// convert to integer coordinates
|
||||||
|
int32 x = (int32)floorf(area.left);
|
||||||
|
int32 y = (int32)floorf(area.top);
|
||||||
|
int32 right = (int32)ceilf(area.right);
|
||||||
|
int32 bottom = (int32)ceilf(area.bottom);
|
||||||
|
|
||||||
|
// offset to left top pixel in source buffer (always B_RGBA32)
|
||||||
|
src += y * srcBPR + x * 4;
|
||||||
|
|
||||||
|
_CopyToFront(src, srcBPR, x, y, right, bottom);
|
||||||
|
|
||||||
|
_DrawCursor(area);
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// _CopyToFront
|
||||||
|
//
|
||||||
|
// * source is assumed to be already at the right offset
|
||||||
|
// * source is assumed to be in B_RGBA32 format
|
||||||
|
// * location in front buffer is calculated
|
||||||
|
// * conversion from B_RGBA32 to format of front buffer is taken care of
|
||||||
|
void
|
||||||
|
HWInterface::_CopyToFront(uint8* src, uint32 srcBPR,
|
||||||
|
int32 x, int32 y,
|
||||||
|
int32 right, int32 bottom) const
|
||||||
|
{
|
||||||
|
RenderingBuffer* frontBuffer = FrontBuffer();
|
||||||
|
|
||||||
|
uint8* dst = (uint8*)frontBuffer->Bits();
|
||||||
|
uint32 dstBPR = frontBuffer->BytesPerRow();
|
||||||
|
|
||||||
|
// transfer, handle colorspace conversion
|
||||||
|
switch (frontBuffer->ColorSpace()) {
|
||||||
|
case B_RGB32:
|
||||||
|
case B_RGBA32: {
|
||||||
|
int32 bytes = (right - x + 1) * 4;
|
||||||
|
|
||||||
|
if (bytes > 0) {
|
||||||
|
// offset to left top pixel in dest buffer
|
||||||
|
dst += y * dstBPR + x * 4;
|
||||||
|
// copy
|
||||||
|
for (; y <= bottom; y++) {
|
||||||
|
memcpy(dst, src, bytes);
|
||||||
|
dst += dstBPR;
|
||||||
|
src += srcBPR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// NOTE: on R5, B_RGB24 bitmaps are not supported by DrawBitmap()
|
||||||
|
case B_RGB24: {
|
||||||
|
// offset to left top pixel in dest buffer
|
||||||
|
dst += y * dstBPR + x * 3;
|
||||||
|
int32 left = x;
|
||||||
|
// copy
|
||||||
|
for (; y <= bottom; y++) {
|
||||||
|
uint8* srcHandle = src;
|
||||||
|
uint8* dstHandle = dst;
|
||||||
|
for (x = left; x <= right; x++) {
|
||||||
|
dstHandle[0] = srcHandle[0];
|
||||||
|
dstHandle[1] = srcHandle[1];
|
||||||
|
dstHandle[2] = srcHandle[2];
|
||||||
|
dstHandle += 3;
|
||||||
|
srcHandle += 4;
|
||||||
|
}
|
||||||
|
dst += dstBPR;
|
||||||
|
src += srcBPR;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case B_RGB16: {
|
||||||
|
// offset to left top pixel in dest buffer
|
||||||
|
dst += y * dstBPR + x * 2;
|
||||||
|
int32 left = x;
|
||||||
|
// copy
|
||||||
|
// TODO: assumes BGR order, does this work on big endian as well?
|
||||||
|
for (; y <= bottom; y++) {
|
||||||
|
uint8* srcHandle = src;
|
||||||
|
uint16* dstHandle = (uint16*)dst;
|
||||||
|
for (x = left; x <= right; x++) {
|
||||||
|
*dstHandle = (uint16)(((srcHandle[2] & 0xf8) << 8) |
|
||||||
|
((srcHandle[1] & 0xfc) << 3) |
|
||||||
|
(srcHandle[0] >> 3));
|
||||||
|
dstHandle ++;
|
||||||
|
srcHandle += 4;
|
||||||
|
}
|
||||||
|
dst += dstBPR;
|
||||||
|
src += srcBPR;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case B_RGB15: {
|
||||||
|
// offset to left top pixel in dest buffer
|
||||||
|
dst += y * dstBPR + x * 2;
|
||||||
|
int32 left = x;
|
||||||
|
// copy
|
||||||
|
// TODO: assumes BGR order, does this work on big endian as well?
|
||||||
|
for (; y <= bottom; y++) {
|
||||||
|
uint8* srcHandle = src;
|
||||||
|
uint16* dstHandle = (uint16*)dst;
|
||||||
|
for (x = left; x <= right; x++) {
|
||||||
|
*dstHandle = (uint16)(((srcHandle[2] & 0xf8) << 7) |
|
||||||
|
((srcHandle[1] & 0xf8) << 2) |
|
||||||
|
(srcHandle[0] >> 3));
|
||||||
|
dstHandle ++;
|
||||||
|
srcHandle += 4;
|
||||||
|
}
|
||||||
|
dst += dstBPR;
|
||||||
|
src += srcBPR;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case B_CMAP8: {
|
||||||
|
#ifndef __HAIKU__
|
||||||
|
// offset to left top pixel in dest buffer
|
||||||
|
dst += y * dstBPR + x;
|
||||||
|
int32 left = x;
|
||||||
|
// copy
|
||||||
|
// TODO: using BScreen will not be an option in the
|
||||||
|
// final implementation, will it? The BBitmap implementation
|
||||||
|
// has a class that handles this, something so useful
|
||||||
|
// should be moved to a more public place.
|
||||||
|
// TODO: assumes BGR order again
|
||||||
|
BScreen screen;
|
||||||
|
for (; y <= bottom; y++) {
|
||||||
|
uint8* srcHandle = src;
|
||||||
|
uint8* dstHandle = dst;
|
||||||
|
for (x = left; x <= right; x++) {
|
||||||
|
*dstHandle = screen.IndexForColor(srcHandle[2],
|
||||||
|
srcHandle[1],
|
||||||
|
srcHandle[0]);
|
||||||
|
dstHandle ++;
|
||||||
|
srcHandle += 4;
|
||||||
|
}
|
||||||
|
dst += dstBPR;
|
||||||
|
src += srcBPR;
|
||||||
|
}
|
||||||
|
#endif // __HAIKU__
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case B_GRAY8: {
|
||||||
|
// offset to left top pixel in dest buffer
|
||||||
|
dst += y * dstBPR + x;
|
||||||
|
int32 left = x;
|
||||||
|
// copy
|
||||||
|
// TODO: assumes BGR order, does this work on big endian as well?
|
||||||
|
for (; y <= bottom; y++) {
|
||||||
|
uint8* srcHandle = src;
|
||||||
|
uint8* dstHandle = dst;
|
||||||
|
for (x = left; x <= right; x++) {
|
||||||
|
*dstHandle = (308 * srcHandle[2] + 600 * srcHandle[1] + 116 * srcHandle[0]) / 1024;
|
||||||
|
dstHandle ++;
|
||||||
|
srcHandle += 4;
|
||||||
|
}
|
||||||
|
dst += dstBPR;
|
||||||
|
src += srcBPR;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "ViewHWInterface::CopyBackToFront() - unsupported front buffer format!\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// _CursorFrame
|
// _CursorFrame
|
||||||
//
|
//
|
||||||
// PRE: the object must be locked
|
// PRE: the object must be locked
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
class RenderingBuffer;
|
class RenderingBuffer;
|
||||||
class ServerCursor;
|
class ServerCursor;
|
||||||
|
class UpdateQueue;
|
||||||
|
|
||||||
class HWInterface : public BLocker {
|
class HWInterface : public BLocker {
|
||||||
public:
|
public:
|
||||||
@@ -60,16 +61,27 @@ class HWInterface : public BLocker {
|
|||||||
virtual RenderingBuffer* BackBuffer() const = 0;
|
virtual RenderingBuffer* BackBuffer() const = 0;
|
||||||
|
|
||||||
// Invalidate is planned to be used for scheduling an area for updating
|
// Invalidate is planned to be used for scheduling an area for updating
|
||||||
virtual status_t Invalidate(const BRect& frame) = 0;
|
status_t Invalidate(const BRect& frame);
|
||||||
// while as CopyBackToFront() actually performs the operation
|
// while as CopyBackToFront() actually performs the operation
|
||||||
virtual status_t CopyBackToFront(const BRect& frame) = 0;
|
status_t CopyBackToFront(const BRect& frame);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
// implement this in derived classes
|
||||||
|
virtual void _DrawCursor(BRect area) const = 0;
|
||||||
|
|
||||||
|
// does the actual transfer and handles color space conversion
|
||||||
|
void _CopyToFront(uint8* src, uint32 srcBPR,
|
||||||
|
int32 x, int32 y,
|
||||||
|
int32 right, int32 bottom) const;
|
||||||
|
|
||||||
BRect _CursorFrame() const;
|
BRect _CursorFrame() const;
|
||||||
|
|
||||||
ServerCursor* fCursor;
|
ServerCursor* fCursor;
|
||||||
bool fCursorVisible;
|
bool fCursorVisible;
|
||||||
BPoint fCursorLocation;
|
BPoint fCursorLocation;
|
||||||
|
|
||||||
|
private:
|
||||||
|
UpdateQueue* fUpdateExecutor;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // HW_INTERFACE_H
|
#endif // HW_INTERFACE_H
|
||||||
|
|||||||
@@ -330,8 +330,7 @@ ViewHWInterface::ViewHWInterface()
|
|||||||
: HWInterface(),
|
: HWInterface(),
|
||||||
fBackBuffer(NULL),
|
fBackBuffer(NULL),
|
||||||
fFrontBuffer(NULL),
|
fFrontBuffer(NULL),
|
||||||
fWindow(NULL),
|
fWindow(NULL)
|
||||||
fUpdateExecutor(new UpdateQueue(this))
|
|
||||||
{
|
{
|
||||||
fDisplayMode.virtual_width = 640;
|
fDisplayMode.virtual_width = 640;
|
||||||
fDisplayMode.virtual_height = 480;
|
fDisplayMode.virtual_height = 480;
|
||||||
@@ -596,64 +595,6 @@ ViewHWInterface::BackBuffer() const
|
|||||||
return fBackBuffer;
|
return fBackBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Invalidate
|
|
||||||
status_t
|
|
||||||
ViewHWInterface::Invalidate(const BRect& frame)
|
|
||||||
{
|
|
||||||
return CopyBackToFront(frame);;
|
|
||||||
|
|
||||||
// TODO: get this working, the locking in the DisplayDriverPainter needs
|
|
||||||
// to be based on locking this object, which essentially means the access
|
|
||||||
// to the back buffer is locked, or more precise the access to the invalid
|
|
||||||
// region scheduled to be copied to the front buffer
|
|
||||||
// fUpdateExecutor->AddRect(frame);
|
|
||||||
// return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// CopyBackToFront
|
|
||||||
status_t
|
|
||||||
ViewHWInterface::CopyBackToFront(const BRect& frame)
|
|
||||||
{
|
|
||||||
if (!fBackBuffer || !fFrontBuffer)
|
|
||||||
return B_NO_INIT;
|
|
||||||
|
|
||||||
// we need to mess with the area, but it is const
|
|
||||||
BRect area(frame);
|
|
||||||
|
|
||||||
if (area.IsValid() && area.Intersects(fFrontBuffer->Bitmap()->Bounds())) {
|
|
||||||
// if we couldn't be sure the bitmaps had the same size:
|
|
||||||
// && area.Intersects(fBackBuffer->Bitmap()->Bounds())) {
|
|
||||||
|
|
||||||
const BBitmap* from = fBackBuffer->Bitmap();
|
|
||||||
// const BBitmap* into = fFrontBuffer->Bitmap();
|
|
||||||
|
|
||||||
// make sure we don't copy out of bounds
|
|
||||||
area = from->Bounds() & area;
|
|
||||||
// area = into->Bounds() & area;
|
|
||||||
|
|
||||||
uint32 srcBPR = fBackBuffer->BytesPerRow();
|
|
||||||
uint8* src = (uint8*)fBackBuffer->Bits();
|
|
||||||
|
|
||||||
// convert to integer coordinates
|
|
||||||
int32 x = (int32)floorf(area.left);
|
|
||||||
int32 y = (int32)floorf(area.top);
|
|
||||||
int32 right = (int32)ceilf(area.right);
|
|
||||||
int32 bottom = (int32)ceilf(area.bottom);
|
|
||||||
|
|
||||||
// offset to left top pixel in source buffer (always B_RGBA32)
|
|
||||||
src += y * srcBPR + x * 4;
|
|
||||||
|
|
||||||
_CopyToFront(src, srcBPR, x, y, right, bottom);
|
|
||||||
|
|
||||||
_DrawCursor(area);
|
|
||||||
|
|
||||||
// update the region on screen
|
|
||||||
fWindow->Invalidate(area);
|
|
||||||
}
|
|
||||||
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// _DrawCursor
|
// _DrawCursor
|
||||||
void
|
void
|
||||||
ViewHWInterface::_DrawCursor(BRect area) const
|
ViewHWInterface::_DrawCursor(BRect area) const
|
||||||
@@ -721,157 +662,6 @@ ViewHWInterface::_DrawCursor(BRect area) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// _CopyToFront
|
|
||||||
//
|
|
||||||
// * source is assumed to be already at the right offset
|
|
||||||
// * source is assumed to be in B_RGBA32 format
|
|
||||||
// * location in front buffer is calculated
|
|
||||||
// * conversion from B_RGBA32 to format of front buffer is taken care of
|
|
||||||
void
|
|
||||||
ViewHWInterface::_CopyToFront(uint8* src, uint32 srcBPR,
|
|
||||||
int32 x, int32 y,
|
|
||||||
int32 right, int32 bottom) const
|
|
||||||
{
|
|
||||||
uint8* dst = (uint8*)fFrontBuffer->Bits();
|
|
||||||
uint32 dstBPR = fFrontBuffer->BytesPerRow();
|
|
||||||
|
|
||||||
// transfer, handle colorspace conversion
|
|
||||||
switch (fFrontBuffer->ColorSpace()) {
|
|
||||||
case B_RGB32:
|
|
||||||
case B_RGBA32: {
|
|
||||||
int32 bytes = (right - x + 1) * 4;
|
|
||||||
|
|
||||||
if (bytes > 0) {
|
|
||||||
// offset to left top pixel in dest buffer
|
|
||||||
dst += y * dstBPR + x * 4;
|
|
||||||
// copy
|
|
||||||
for (; y <= bottom; y++) {
|
|
||||||
memcpy(dst, src, bytes);
|
|
||||||
dst += dstBPR;
|
|
||||||
src += srcBPR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// NOTE: on R5, B_RGB24 bitmaps are not supported by DrawBitmap()
|
|
||||||
case B_RGB24: {
|
|
||||||
// offset to left top pixel in dest buffer
|
|
||||||
dst += y * dstBPR + x * 3;
|
|
||||||
int32 left = x;
|
|
||||||
// copy
|
|
||||||
for (; y <= bottom; y++) {
|
|
||||||
uint8* srcHandle = src;
|
|
||||||
uint8* dstHandle = dst;
|
|
||||||
x = left;
|
|
||||||
for (; x <= right; x++) {
|
|
||||||
dstHandle[0] = srcHandle[0];
|
|
||||||
dstHandle[1] = srcHandle[1];
|
|
||||||
dstHandle[2] = srcHandle[2];
|
|
||||||
dstHandle += 3;
|
|
||||||
srcHandle += 4;
|
|
||||||
}
|
|
||||||
dst += dstBPR;
|
|
||||||
src += srcBPR;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case B_RGB16: {
|
|
||||||
// offset to left top pixel in dest buffer
|
|
||||||
dst += y * dstBPR + x * 2;
|
|
||||||
int32 left = x;
|
|
||||||
// copy
|
|
||||||
// TODO: assumes BGR order, does this work on big endian as well?
|
|
||||||
for (; y <= bottom; y++) {
|
|
||||||
uint8* srcHandle = src;
|
|
||||||
uint16* dstHandle = (uint16*)dst;
|
|
||||||
x = left;
|
|
||||||
for (; x <= right; x++) {
|
|
||||||
*dstHandle = (uint16)(((srcHandle[2] & 0xf8) << 8) |
|
|
||||||
((srcHandle[1] & 0xfc) << 3) |
|
|
||||||
(srcHandle[0] >> 3));
|
|
||||||
dstHandle ++;
|
|
||||||
srcHandle += 4;
|
|
||||||
}
|
|
||||||
dst += dstBPR;
|
|
||||||
src += srcBPR;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case B_RGB15: {
|
|
||||||
// offset to left top pixel in dest buffer
|
|
||||||
dst += y * dstBPR + x * 2;
|
|
||||||
int32 left = x;
|
|
||||||
// copy
|
|
||||||
// TODO: assumes BGR order, does this work on big endian as well?
|
|
||||||
for (; y <= bottom; y++) {
|
|
||||||
uint8* srcHandle = src;
|
|
||||||
uint16* dstHandle = (uint16*)dst;
|
|
||||||
x = left;
|
|
||||||
for (; x <= right; x++) {
|
|
||||||
*dstHandle = (uint16)(((srcHandle[2] & 0xf8) << 7) |
|
|
||||||
((srcHandle[1] & 0xf8) << 2) |
|
|
||||||
(srcHandle[0] >> 3));
|
|
||||||
dstHandle ++;
|
|
||||||
srcHandle += 4;
|
|
||||||
}
|
|
||||||
dst += dstBPR;
|
|
||||||
src += srcBPR;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case B_CMAP8: {
|
|
||||||
// offset to left top pixel in dest buffer
|
|
||||||
dst += y * dstBPR + x;
|
|
||||||
int32 left = x;
|
|
||||||
// copy
|
|
||||||
// TODO: using BScreen will not be an option in the
|
|
||||||
// final implementation, will it? The BBitmap implementation
|
|
||||||
// has a class that handles this, something so useful
|
|
||||||
// should be moved to a more public place.
|
|
||||||
// TODO: assumes BGR order again
|
|
||||||
BScreen screen;
|
|
||||||
for (; y <= bottom; y++) {
|
|
||||||
uint8* srcHandle = src;
|
|
||||||
uint8* dstHandle = dst;
|
|
||||||
x = left;
|
|
||||||
for (; x <= right; x++) {
|
|
||||||
*dstHandle = screen.IndexForColor(srcHandle[2],
|
|
||||||
srcHandle[1],
|
|
||||||
srcHandle[0]);
|
|
||||||
dstHandle ++;
|
|
||||||
srcHandle += 4;
|
|
||||||
}
|
|
||||||
dst += dstBPR;
|
|
||||||
src += srcBPR;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case B_GRAY8: {
|
|
||||||
// offset to left top pixel in dest buffer
|
|
||||||
dst += y * dstBPR + x;
|
|
||||||
int32 left = x;
|
|
||||||
// copy
|
|
||||||
// TODO: assumes BGR order, does this work on big endian as well?
|
|
||||||
for (; y <= bottom; y++) {
|
|
||||||
uint8* srcHandle = src;
|
|
||||||
uint8* dstHandle = dst;
|
|
||||||
x = left;
|
|
||||||
for (; x <= right; x++) {
|
|
||||||
*dstHandle = (308 * srcHandle[2] + 600 * srcHandle[1] + 116 * srcHandle[0]) / 1024;
|
|
||||||
dstHandle ++;
|
|
||||||
srcHandle += 4;
|
|
||||||
}
|
|
||||||
dst += dstBPR;
|
|
||||||
src += srcBPR;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
fprintf(stderr, "ViewHWInterface::CopyBackToFront() - unsupported front buffer format!\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*void ViewHWInterface::CopyBitmap(ServerBitmap *bitmap, const BRect &source, const BRect &dest, const DrawData *d)
|
/*void ViewHWInterface::CopyBitmap(ServerBitmap *bitmap, const BRect &source, const BRect &dest, const DrawData *d)
|
||||||
|
|||||||
@@ -53,23 +53,16 @@ class ViewHWInterface : public HWInterface {
|
|||||||
virtual RenderingBuffer* FrontBuffer() const;
|
virtual RenderingBuffer* FrontBuffer() const;
|
||||||
virtual RenderingBuffer* BackBuffer() const;
|
virtual RenderingBuffer* BackBuffer() const;
|
||||||
|
|
||||||
virtual status_t Invalidate(const BRect& frame);
|
protected:
|
||||||
virtual status_t CopyBackToFront(const BRect& area);
|
virtual void _DrawCursor(BRect area) const;
|
||||||
|
|
||||||
private:
|
|
||||||
void _DrawCursor(BRect area) const;
|
|
||||||
void _CopyToFront(uint8* src, uint32 srcBPR,
|
|
||||||
int32 x, int32 y,
|
|
||||||
int32 right, int32 bottom) const;
|
|
||||||
|
|
||||||
|
private:
|
||||||
BitmapBuffer* fBackBuffer;
|
BitmapBuffer* fBackBuffer;
|
||||||
BitmapBuffer* fFrontBuffer;
|
BitmapBuffer* fFrontBuffer;
|
||||||
|
|
||||||
CardWindow* fWindow;
|
CardWindow* fWindow;
|
||||||
|
|
||||||
display_mode fDisplayMode;
|
display_mode fDisplayMode;
|
||||||
|
|
||||||
UpdateQueue* fUpdateExecutor;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // VIEW_GRAPHICS_CARD_H
|
#endif // VIEW_GRAPHICS_CARD_H
|
||||||
|
|||||||
Reference in New Issue
Block a user