Skip to content

Commit

Permalink
[feat] SDL2: update parts of window like a real device (#626)
Browse files Browse the repository at this point in the history
This commit uses a viewport to draw only a subset of the blitbuffer onto the
rectangle to be updated in the SDL texture.

Without this, there are cases where a full screen (or at least bigger) refresh
is required that will not be obvious without first testing on a real device.
See koreader/koreader#3804

Also fixes `EMULATE_READER_FLASH`, which was accidentally broken in 981bd40
  • Loading branch information
Frenzie committed Mar 30, 2018
1 parent ff9286a commit 2ecc6d1
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 7 deletions.
5 changes: 5 additions & 0 deletions ffi/SDL2_0.lua
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,11 @@ function S.destroyTexture(texture)
SDL.SDL_DestroyTexture(texture)
end

local rect = ffi.metatype("SDL_Rect", {})
function S.rect(x, y, w, h)
return rect(x, y, w, h)
end

-- one SDL event can generate more than one event for koreader,
-- so this represents a FIFO queue
local inputQueue = {}
Expand Down
7 changes: 6 additions & 1 deletion ffi/SDL2_0_h.lua
Original file line number Diff line number Diff line change
Expand Up @@ -606,7 +606,12 @@ static const int SDL_WINDOWPOS_UNDEFINED = 536805376;
static const int SDL_WINDOW_FULLSCREEN = 1;
static const int SDL_WINDOW_FULLSCREEN_DESKTOP = 4097;
static const int SDL_WINDOW_RESIZABLE = 32;
static const int SDL_TEXTUREACCESS_STREAMING = 1;
typedef enum
{
SDL_TEXTUREACCESS_STATIC,
SDL_TEXTUREACCESS_STREAMING,
SDL_TEXTUREACCESS_TARGET
} SDL_TextureAccess;
static const int SDL_PIXELFORMAT_ARGB8888 = 372645892;
static const int SDL_PIXELFORMAT_RGBA8888 = 373694468;
static const int SDL_PIXELFORMAT_ABGR8888 = 376840196;
Expand Down
24 changes: 18 additions & 6 deletions ffi/framebuffer_SDL2_0.lua
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ function framebuffer:resize(w, h)

if not self.dummy then
self:_newBB(w, h)
SDL.w = w
SDL.h = h
else
self.bb:free()
self.bb = BB.new(600, 800)
Expand Down Expand Up @@ -72,13 +74,23 @@ function framebuffer:_newBB(w, h)
end
end

function framebuffer:_render(bb)
function framebuffer:_render(bb, x, y, w, h)
w, x = BB.checkBounds(w or bb:getWidth(), x or 0, 0, bb:getWidth(), 0xFFFF)
h, y = BB.checkBounds(h or bb:getHeight(), y or 0, 0, bb:getHeight(), 0xFFFF)
x, y, w, h = bb:getPhysicalRect(x, y, w, h)

if bb:getInverse() == 1 then
self.invert_bb:invertblitFrom(bb)
SDL.SDL.SDL_UpdateTexture(SDL.texture, nil, self.invert_bb.data, self.invert_bb.pitch)
else
SDL.SDL.SDL_UpdateTexture(SDL.texture, nil, bb.data, bb.pitch)
bb = self.invert_bb
end

-- A viewport is a Blitbuffer object that works on a rectangular
-- subset of the underlying memory without allocating new memory.
local bb_rect = bb:viewport(x, y, w, h)
local sdl_rect = SDL.rect(x, y, w, h)

SDL.SDL.SDL_UpdateTexture(SDL.texture, sdl_rect, bb_rect.data, bb_rect.pitch)

SDL.SDL.SDL_RenderClear(SDL.renderer)
SDL.SDL.SDL_RenderCopy(SDL.renderer, SDL.texture, nil, nil)
SDL.SDL.SDL_RenderPresent(SDL.renderer)
Expand All @@ -101,13 +113,13 @@ function framebuffer:refreshFullImp(x, y, w, h)
local flash = os.getenv("EMULATE_READER_FLASH")
if flash then
self.sdl_bb:invertRect(x, y, w, h)
self:_render(bb)
self:_render(self.sdl_bb, x, y, w, h)
util.usleep(tonumber(flash)*1000)
self.sdl_bb:setRotation(bb:getRotation())
self.sdl_bb:setInverse(bb:getInverse())
self.sdl_bb:blitFrom(bb, x, y, x, y, w, h)
end
self:_render(bb)
self:_render(bb, x, y, w, h)
end

function framebuffer:setWindowTitle(new_title)
Expand Down

0 comments on commit 2ecc6d1

Please sign in to comment.