根據 Jserv 大的淺談 Google Skia 圖形處理引擎,得知 skia 只能畫在 Memory buffer 上,那麼,可以直接畫在 Framebuffer 上嗎??
Jserv 大文章裡的例子,SkBitmap 得先呼叫 allocPixels() 來配置所需要的 Memory buffer,根據 SkBitmap.h 裡的宣告,allocPixels 事實上是使用 allocator 來配置所需要的 Memory buffer,如果未指定,會以 stdalloc(HeapAllocator) 來進行配置。因此如果要直接使用 framebuffer,可以繼承 SkBitmap::Allocator 類別之後,改寫 allocPixelRef() 來達到目的。
大致的代碼就像這樣子:[c]
#include “SkTypes.h”
#include “SkRefCnt.h”
#include “SkBitmap.h”
#include “SkDevice.h”
#include “SkPaint.h”
#include “SkRect.h”
#include “SkMallocPixelRef.h”
class FrameBufferAllocator: public SkBitmap::Allocator
{
public:
FrameBufferAllocator();
virtual ~FrameBufferAllocator();
virtual bool allocPixelRef(SkBitmap*, SkColorTable*);
private:
char* m_addr;
int fd;
};
FrameBufferAllocator::FrameBufferAllocator()
{
}
FrameBufferAllocator::~FrameBufferAllocator()
{
// munmap framebuffer pointer.
// close the framebuffer device we opened
}
bool FrameBufferAllocator::allocPixelRef(SkBitmap* dst, SkColorTable* ctable)
{
size_t size = dst->getSize();
// open framebuffer
fd = open( “/dev/fb0”, O_RDWR );
// setup framebuffer device via ioctl.
// mmap framebuffer
m_addr = (char *)mmap(0, screensize, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
// call original procedures in HeapAllocator::
dst->setPixelRef(new SkMallocPixelRef(m_addr, size, ctable))->unref();
dst->lockPixels();
return true;
}
[/c]
接著,Jserv 大的範例只要修改一行:[c]
bitmap.allocPixels( new FrameBufferAllocator, NULL );
[/c]
就可以順利運作了。
p.s. 在 link libskia.a 時,遇到很鳥的狀況,skia 的 Makefile 在製作時,是直接以帶有路徑的 .o 去作,而我 toolchain 的 gcc 居然無法處理,必須要以沒有路徑的 .o 去重新製作,這樣才能 link 成功。