mirror of
https://github.com/koreader/koreader.git
synced 2025-12-13 20:36:53 +01:00
Fix partial HW dithered refreshes sometimes appearing to shift refreshed content (#6267)
* Fix HW dithered partial refreshes sometimes behaving as if the refreshed content had moved a few pixels to the side... Probably a kernel issue with the alignment fixup in the EPDC? * Get rid of the legacy coordinates fixup It shouldn't be necessary anymore. And I'd rather fix the root cause, anyway. * Bump base (https://github.com/koreader/koreader-base/pull/1116) * Missed a few DIVs in #6224
This commit is contained in:
2
base
2
base
Submodule base updated: 3c3b7ca24b...21ac242ab2
@@ -112,7 +112,7 @@ function ReaderCropping:onPageCrop(mode)
|
||||
self.ui:handleEvent(Event:new("SetZoomMode", "page", "cropping"))
|
||||
end
|
||||
self.ui:handleEvent(Event:new("SetDimensions",
|
||||
Geom:new{w = Screen:getWidth(), h = Screen:getHeight()*11/12})
|
||||
Geom:new{w = Screen:getWidth(), h = math.floor(Screen:getHeight()*11/12)})
|
||||
)
|
||||
self.bbox_widget = BBoxWidget:new{
|
||||
crop = self,
|
||||
|
||||
@@ -154,7 +154,7 @@ function ReaderFont:onShowFontMenu()
|
||||
title = self.font_menu_title,
|
||||
item_table = self.face_table,
|
||||
width = Screen:getWidth() - 100,
|
||||
height = Screen:getHeight() / 2,
|
||||
height = math.floor(Screen:getHeight() * 0.5),
|
||||
single_line = true,
|
||||
perpage_custom = 8,
|
||||
}
|
||||
|
||||
@@ -707,7 +707,7 @@ function ReaderHighlight:onHoldPan(_, ges)
|
||||
-- Also, we are not able to move hold_pos.x out of screen,
|
||||
-- so if we started on the right page, ignore top left corner,
|
||||
-- and if we started on the left page, ignore bottom right corner.
|
||||
local screen_half_width = math.floor(Screen:getWidth() * 1/2)
|
||||
local screen_half_width = math.floor(Screen:getWidth() * 0.5)
|
||||
if self.hold_pos.x >= screen_half_width and is_in_prev_page_corner then
|
||||
return true
|
||||
elseif self.hold_pos.x <= screen_half_width and is_in_next_page_corner then
|
||||
|
||||
@@ -634,7 +634,7 @@ function ReaderRolling:onGotoXPointer(xp, marker_xp)
|
||||
if BD.mirroredUILayout() then
|
||||
-- In the middle margin, on the right of text
|
||||
-- Same trick as below, assuming page2_x is equal to page 1 right x
|
||||
screen_x = Screen:getWidth() / 2
|
||||
screen_x = math.floor(Screen:getWidth() * 0.5)
|
||||
local page2_x = self.ui.document:getPageOffsetX(self.ui.document:getCurrentPage()+1)
|
||||
marker_w = page2_x + marker_w - screen_x
|
||||
screen_x = screen_x - marker_w
|
||||
@@ -648,7 +648,7 @@ function ReaderRolling:onGotoXPointer(xp, marker_xp)
|
||||
-- In the middle margin, on the left of text
|
||||
-- This is a bit tricky with how the middle margin is sized
|
||||
-- by crengine (see LVDocView::updateLayout() in lvdocview.cpp)
|
||||
screen_x = Screen:getWidth() / 2
|
||||
screen_x = math.floor(Screen:getWidth() * 0.5)
|
||||
local page2_x = self.ui.document:getPageOffsetX(self.ui.document:getCurrentPage()+1)
|
||||
marker_w = page2_x + marker_w - screen_x
|
||||
end
|
||||
@@ -1086,7 +1086,7 @@ function ReaderRolling:showEngineProgress(percent)
|
||||
-- so it does not override the footer or a bookmark dogear
|
||||
local x = 0
|
||||
local y = Size.margin.small
|
||||
local w = Screen:getWidth() / 3
|
||||
local w = math.floor(Screen:getWidth() / 3)
|
||||
local h = Size.line.progress
|
||||
if self.engine_progress_widget then
|
||||
self.engine_progress_widget:setPercentage(percent)
|
||||
|
||||
@@ -32,7 +32,7 @@ local TweakInfoWidget = InputContainer:new{
|
||||
is_global_default = nil,
|
||||
toggle_global_default_callback = function() end,
|
||||
modal = true,
|
||||
width = Screen:getWidth()*3/4,
|
||||
width = math.floor(Screen:getWidth() * 0.75),
|
||||
}
|
||||
|
||||
function TweakInfoWidget:init()
|
||||
|
||||
@@ -231,7 +231,7 @@ When the book's language tag is not among our presets, no specific features will
|
||||
title = _("Language tags (and hyphenation dictionaries) used since start up"),
|
||||
text = status_text,
|
||||
text_face = Font:getFace("smallinfont"),
|
||||
height = Screen:getHeight() * 4/5,
|
||||
height = math.floor(Screen:getHeight() * 0.8),
|
||||
})
|
||||
end,
|
||||
keep_menu_open = true,
|
||||
|
||||
@@ -499,7 +499,7 @@ function Translator:_showTranslation(text, target_lang, source_lang)
|
||||
-- Showing the translation target language in this title may make
|
||||
-- it quite long and wrapped, taking valuable vertical spacing
|
||||
text = table.concat(output, "\n"),
|
||||
height = Screen:getHeight() * 4/5,
|
||||
height = math.floor(Screen:getHeight() * 0.8),
|
||||
justified = G_reader_settings:nilOrTrue("dict_justify"),
|
||||
})
|
||||
end
|
||||
|
||||
@@ -962,6 +962,21 @@ function UIManager:_refresh(mode, region, dither)
|
||||
table.insert(self._refresh_stack, {mode = mode, region = region, dither = dither})
|
||||
end
|
||||
|
||||
|
||||
-- A couple helper functions to compute aligned values...
|
||||
-- c.f., <linux/kernel.h> & ffi/framebuffer_linux.lua
|
||||
local function ALIGN_DOWN(x, a)
|
||||
-- x & ~(a-1)
|
||||
local mask = a - 1
|
||||
return bit.band(x, bit.bnot(mask))
|
||||
end
|
||||
|
||||
local function ALIGN_UP(x, a)
|
||||
-- (x + (a-1)) & ~(a-1)
|
||||
local mask = a - 1
|
||||
return bit.band(x + mask, bit.bnot(mask))
|
||||
end
|
||||
|
||||
--- Repaints dirty widgets.
|
||||
function UIManager:_repaint()
|
||||
-- flag in which we will record if we did any repaints at all
|
||||
@@ -1031,12 +1046,34 @@ function UIManager:_repaint()
|
||||
refresh.dither = nil
|
||||
end
|
||||
dbg:v("triggering refresh", refresh)
|
||||
-- NOTE: We overshoot by 1px to account for potential off-by-ones.
|
||||
-- This may not strictly be needed anymore, and is blatantly unneeded for full-screen updates,
|
||||
-- but checkBounds & getPhysicalRect will sanitize that in mxc_update @ ffi/framebuffer_mxcfb ;).
|
||||
-- NOTE: If we're requesting hardware dithering on a partial update, make sure the rectangle is using
|
||||
-- coordinates aligned to the previous multiple of 8, and dimensions aligned to the next multiple of 8.
|
||||
-- Otherwise, some unlucky coordinates will play badly with the PxP's own alignment constraints,
|
||||
-- leading to a refresh where content appears to have moved a few pixels to the side...
|
||||
-- (Sidebar: this is probably a kernel issue, the EPDC driver is responsible for the alignment fixup,
|
||||
-- c.f., epdc_process_update @ drivers/video/fbdev/mxc/mxc_epdc_v2_fb.c on a Kobo Mk. 7 kernel...).
|
||||
if refresh.dither then
|
||||
-- NOTE: Make sure the coordinates are positive, first! Otherwise, we'd gladly align further down below 0,
|
||||
-- which would skew the rectangle's position/dimension after checkBounds...
|
||||
local x_fixup = 0
|
||||
if refresh.region.x > 0 then
|
||||
local x_orig = refresh.region.x
|
||||
refresh.region.x = ALIGN_DOWN(x_orig, 8)
|
||||
x_fixup = x_orig - refresh.region.x
|
||||
end
|
||||
local y_fixup = 0
|
||||
if refresh.region.y > 0 then
|
||||
local y_orig = refresh.region.y
|
||||
refresh.region.y = ALIGN_DOWN(y_orig, 8)
|
||||
y_fixup = y_orig - refresh.region.y
|
||||
end
|
||||
-- And also make sure we won't be inadvertently cropping our rectangle in case of severe alignment fixups...
|
||||
refresh.region.w = ALIGN_UP(refresh.region.w + (x_fixup * 2), 8)
|
||||
refresh.region.h = ALIGN_UP(refresh.region.h + (y_fixup * 2), 8)
|
||||
end
|
||||
Screen[refresh_methods[refresh.mode]](Screen,
|
||||
refresh.region.x - 1, refresh.region.y - 1,
|
||||
refresh.region.w + 2, refresh.region.h + 2,
|
||||
refresh.region.x, refresh.region.y,
|
||||
refresh.region.w, refresh.region.h,
|
||||
refresh.dither)
|
||||
end
|
||||
self._refresh_stack = {}
|
||||
|
||||
@@ -220,7 +220,7 @@ function ConfigOption:init()
|
||||
-- They will carry the left default_option_hpadding, but the in-between
|
||||
-- one (and the right one) will be carried by the option items.
|
||||
-- (Both these variables are between 0 and 1 and represent a % of screen width)
|
||||
local default_name_align_right = (max_option_name_width + default_option_hpadding + 2*padding_small) / Screen:getWidth()
|
||||
local default_name_align_right = math.floor((max_option_name_width + default_option_hpadding + 2*padding_small) / Screen:getWidth())
|
||||
default_name_align_right = math.max(default_name_align_right, 0.25)
|
||||
default_name_align_right = math.min(default_name_align_right, 0.5)
|
||||
local default_item_align_center = 1 - default_name_align_right
|
||||
|
||||
@@ -76,7 +76,7 @@ function ConfirmBox:init()
|
||||
local text_widget = TextBoxWidget:new{
|
||||
text = self.text,
|
||||
face = self.face,
|
||||
width = Screen:getWidth()*2/3,
|
||||
width = math.floor(Screen:getWidth() * 2/3),
|
||||
}
|
||||
local content = HorizontalGroup:new{
|
||||
align = "center",
|
||||
|
||||
@@ -107,7 +107,7 @@ function InfoMessage:init()
|
||||
|
||||
local text_width
|
||||
if self.width == nil then
|
||||
text_width = Screen:getWidth() * 2 / 3
|
||||
text_width = math.floor(Screen:getWidth() * 2/3)
|
||||
else
|
||||
text_width = self.width - image_widget:getSize().w
|
||||
if text_width < 0 then
|
||||
|
||||
@@ -87,7 +87,7 @@ function MultiConfirmBox:init()
|
||||
TextBoxWidget:new{
|
||||
text = self.text,
|
||||
face = self.face,
|
||||
width = Screen:getWidth()*2/3,
|
||||
width = math.floor(Screen:getWidth() * 2/3),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ function Notification:init()
|
||||
self[1] = CenterContainer:new{
|
||||
dimen = Geom:new{
|
||||
w = Screen:getWidth(),
|
||||
h = Screen:getHeight()/10,
|
||||
h = math.floor(Screen:getHeight() / 10),
|
||||
},
|
||||
FrameContainer:new{
|
||||
background = Blitbuffer.COLOR_WHITE,
|
||||
|
||||
@@ -6,7 +6,7 @@ Example:
|
||||
local Foo = TextBoxWidget:new{
|
||||
face = Font:getFace("cfont", 25),
|
||||
text = 'We can show multiple lines.\nFoo.\nBar.',
|
||||
-- width = Screen:getWidth()*2/3,
|
||||
-- width = math.floor(Screen:getWidth() * 2/3),
|
||||
}
|
||||
UIManager:show(Foo)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user