Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Re-enable HW dithering on Kindle #1034

Merged
merged 3 commits into from
Jan 31, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
70 changes: 36 additions & 34 deletions ffi-cdecl/include/einkfb.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// NOTE: Upstream kernels available here: https://www.amazon.com/gp/help/customer/display.html?nodeId=200203720

#ifndef _EINKFB_H
#define _EINKFB_H

Expand Down Expand Up @@ -35,7 +37,7 @@ struct raw_image_t
int xres, // image's width, in pixels
yres, // image's height
bpp; // image's pixel (bit) depth

__u8 start[]; // actual start of image
};
typedef struct raw_image_t raw_image_t;
Expand All @@ -46,7 +48,7 @@ struct image_t
xlen, // image's actual width, used for rowbyte & memory size calculations
yres, // image's height
bpp; // image's pixel (bit) depth

__u8 *start; // pointer to start of image
};
typedef struct image_t image_t;
Expand All @@ -62,17 +64,17 @@ enum splash_screen_type

//splash_screen_powering_off_wireless, // Deprecated.
//splash_screen_powering_on_wireless, // Deprecated.

//splash_screen_exit, // Deprecated.
splash_screen_logo = 5,

//splash_screen_usb_internal, // Deprecated.
//splash_screen_usb_external, // Deprecated.
//splash_screen_usb, // Deprecated.

//splash_screen_sleep, // Deprecated.
//splash_screen_update, // Deprecated.

//num_splash_screens, // Deprecated.

// Composite splash screens & messages.
Expand All @@ -81,22 +83,22 @@ enum splash_screen_type
//splash_screen_drivemode_1, // Deprecated.
//splash_screen_drivemode_2, // Deprecated.
//splash_screen_drivemode_3, // Deprecated.

splash_screen_power_off_clear_screen = 16,// Message: clear screen and power down controller.
//splash_screen_screen_saver_picture, // Deprecated.

splash_screen_shim_picture = 18, // Message: shim wants a picture displayed.

splash_screen_lowbatt, // Picture: Not composite, post-legacy ordering (Mario only).
splash_screen_reboot, // Picture: Composite (not used on Fiona).
splash_screen_update_initial, // Composite software-update screens.

splash_screen_update_initial, // Composite software-update screens.
splash_screen_update_success, //
splash_screen_update_failure, //
splash_screen_update_failure_no_wait, //

splash_screen_repair_needed, // More composite screens.
splash_screen_boot, //
splash_screen_boot, //

splash_screen_invalid = -1
};
Expand All @@ -119,20 +121,20 @@ enum fx_type
//
fx_mask = 11, // Only for use with update_area_t's non-NULL buffer which_fx.
fx_buf_is_mask = 14, // Same as fx_mask, but doesn't require a doubling (i.e., the buffer & mask are the same).

fx_none = -1, // No legacy-FX to apply.

// Screen-update FX, supported by HAL.
//
fx_flash = 20, // Only for use with update_area_t (for faking a flashing update).
fx_invert = 21, // Only for use with update_area_t (only inverts output data).
fx_update_partial = 0, // Higher-speed, lower-fidelity update at bit depth's number of grays (aka non-flashing).

fx_update_partial = 0, // Higher-speed, lower-fidelity update at bit depth's number of grays (aka non-flashing).
fx_update_full = 1, // Higher-fidelity, lower speed update at bit depth's number of grays (aka flashing).

fx_update_fast = 2, // Sacrifices all fidelity for speed (will be non-flashing).
fx_update_slow = 3, // Sacrifices any speed for fidelity (will be flashing).

fx_buffer_load = 99, // Just load the hardware buffer; don't update the display.
fx_buffer_display_partial = 100, // Display whatever's in the hardware's buffer, non-flashing style.
fx_buffer_display_full = 101 // Display whatever's in the hardware's buffer, flashing style.
Expand Down Expand Up @@ -160,7 +162,7 @@ typedef enum fx_type fx_type;
(fx_buffer_display_partial == (f)) || \
(fx_update_partial == (f)) || \
(fx_update_fast == (f)))

#define UPDATE_AREA_FULL(f) \
(UPDATE_AREA_FX(f) || \
(fx_buffer_display_full == (f)) || \
Expand Down Expand Up @@ -191,7 +193,7 @@ typedef enum fx_type fx_type;
((fx_buffer_load == (f)) || \
(fx_buffer_display_partial == (f)) || \
(fx_buffer_display_full == (f)))

#define SKIP_BUFFERS_EQUAL(f, c) \
(UPDATE_MODE_BUFFER(f) || \
(fx_update_slow == (f)) || \
Expand All @@ -214,7 +216,7 @@ struct fx_t
{
fx_type update_mode, // Screen-update FX: fx_update_full | fx_update_partial.
which_fx; // Shim (legacy) FX.

int num_exclude_rects; // 0..MAX_EXCLUDE_RECTS.
rect_t exclude_rects[MAX_EXCLUDE_RECTS];
};
Expand All @@ -239,9 +241,9 @@ struct update_area_t
//
int x1, y1, // Top-left...
x2, y2; // ...bottom-right.

fx_type which_fx; // FX to use.

__u8 *buffer; // If NULL, extract from framebuffer, top-left to bottom-right, by rowbytes.
};
typedef struct update_area_t update_area_t;
Expand Down Expand Up @@ -274,10 +276,10 @@ typedef enum orientation_t orientation_t;

#define ORIENTATION_PORTRAIT(o) \
((orientation_portrait == (o)) || (orientation_portrait_upside_down == (o)))

#define ORIENTATION_LANDSCAPE(o) \
((orientation_landscape == (o)) || (orientation_landscape_upside_down == (o)))

#define ORIENTATION_SAME(o1, o2) \
((ORIENTATION_PORTRAIT(o1) && ORIENTATION_PORTRAIT(o2)) || \
(ORIENTATION_LANDSCAPE(o1) && ORIENTATION_LANDSCAPE(o2)))
Expand All @@ -286,27 +288,27 @@ enum einkfb_events_t
{
einkfb_event_update_display = 0, // FBIO_EINK_UPDATE_DISPLAY
einkfb_event_update_display_area, // FBIO_EINK_UPDATE_DISPLAY_AREA

einkfb_event_blank_display, // FBIOBLANK (fb.h)
einkfb_event_rotate_display, // FBIO_EINK_SET_DISPLAY_ORIENTATION

einkfb_event_null = -1
};
typedef enum einkfb_events_t einkfb_events_t;

struct einkfb_event_t
{
einkfb_events_t event; // Not all einkfb_events_t use all of the einkfb_event_t fields.

fx_type update_mode; // Screen-update FX: fx_update_full | fx_update_partial.

// Note: The bottom-right (x2, y2) coordinate is actually such that (x2 - x1) and (y2 - y1)
// are xres and yres, respectively, when normally xres and yres would be
// (x2 - x1) + 1 and (y2 - y1) + 1, respectively.
//
int x1, y1, // Top-left...
x2, y2; // ...bottom-right.

orientation_t orientation; // Display rotated into this orientation.
};
typedef struct einkfb_event_t einkfb_event_t;
Expand All @@ -323,7 +325,7 @@ enum progressbar_badge_t
{
progressbar_badge_success,
progressbar_badge_failure,

progressbar_badge_none
};
typedef enum progressbar_badge_t progressbar_badge_t;
Expand All @@ -338,14 +340,14 @@ typedef enum sleep_behavior_t sleep_behavior_t;
enum contrast_t
{
contrast_off,

contrast_light,
contrast_medium,
contrast_dark,

contrast_lighter,
contrast_lightest,

contrast_darker,
contrast_darkest
};
Expand Down
3 changes: 3 additions & 0 deletions ffi-cdecl/include/mxcfb-cervantes.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
* http://www.gnu.org/copyleft/lgpl.html
*/

// NOTE: Upstream kernels available here: https://github.com/bq/linux-e60qh2/tree/e60qh2 (as well as the other linux- repos).
// See also https://blog.bq.com/es/bq-ereaders-developers-program/

/*
* @file arch-mxc/ mxcfb.h
*
Expand Down
4 changes: 3 additions & 1 deletion ffi-cdecl/include/mxcfb-kindle.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
/*
* Copyright (C) 2004-2015 Freescale Semiconductor, Inc. All Rights Reserved.
*
* NOTE: Upstream kernels available here: https://www.amazon.com/gp/help/customer/display.html?nodeId=200203720
*
* - Modified by houqp, added mxcfb_update_data struct from GeekMaster's
* video player, refer to:
* http://www.mobileread.com/forums/showthread.php?t=177455&page=10
Expand Down Expand Up @@ -181,7 +183,7 @@ struct mxcfb_rect {
/* Display temperature */
#define TEMP_USE_AMBIENT 0x1000
/* Gone w/ KOA2 */
#define TEMP_USE_PAPYRUS 0X1001
#define TEMP_USE_PAPYRUS 0x1001

/* PW2, Gone w/ KOA2 */
#define TEMP_USE_AUTO 0x1001
Expand Down
5 changes: 3 additions & 2 deletions ffi-cdecl/include/mxcfb-kobo.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2004-2015 Freescale Semiconductor, Inc. All Rights Reserved.
*
* NOTE: Upstream kernels available here: https://github.com/kobolabs/Kobo-Reader/tree/master/hw
* - slightly modified (commented out include of fb.h) for Lua integration
* - Frankensteined w/ Mark 6 stuff -- NiLuJe
* - Frankensteined w/ Mark 7 stuff -- NiLuJe
Expand Down Expand Up @@ -162,12 +163,12 @@ struct mxcfb_rect {
/* Mark 7 */
#define EPDC_FLAG_TEST_COLLISION 0x200
#define EPDC_FLAG_GROUP_UPDATE 0x400
/* Nickel: only for alyssum and above */
/* Nickel: only for alyssum and above (i.e., Mk. 6) */
#define EPDC_FLAG_USE_DITHERING_Y1 0x2000
#define EPDC_FLAG_USE_DITHERING_Y4 0x4000
#define EPDC_FLAG_USE_REGAL 0x8000

/* Nickel */
/* Nickel (gone on Mk. 7) */
#define EPDC_FLAG_USE_DITHERING_NTX_D8 0x100000

/* Mark 7 */
Expand Down
50 changes: 33 additions & 17 deletions ffi/framebuffer_mxcfb.lua
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ local function refresh_k51(fb, refreshtype, waveform_mode, x, y, w, h)
return mxc_update(fb, C.MXCFB_SEND_UPDATE, refarea, refreshtype, waveform_mode, x, y, w, h)
end

local function refresh_zelda(fb, refreshtype, waveform_mode, x, y, w, h)
local function refresh_zelda(fb, refreshtype, waveform_mode, x, y, w, h, dither)
local refarea = ffi.new("struct mxcfb_update_data_zelda[1]")
-- only for Amazon's driver, try to mostly follow what the stock reader does...
if waveform_mode == C.WAVEFORM_MODE_ZELDA_GLR16 then
Expand All @@ -345,11 +345,20 @@ local function refresh_zelda(fb, refreshtype, waveform_mode, x, y, w, h)
end
-- NOTE: Since there's no longer a distinction between GC16_FAST & GC16, we're done!
refarea[0].temp = C.TEMP_USE_AMBIENT
-- NOTE: Dithering appears to behave differently than on Kobo, so, forget about it until someone with the device cares enough...
refarea[0].dither_mode = C.EPDC_FLAG_USE_DITHERING_PASSTHROUGH
refarea[0].quant_bit = 0;
-- Enable the appropriate flag when requesting what amounts to a 2bit update
if waveform_mode == C.WAVEFORM_MODE_DU then
-- Did we request HW dithering?
if dither then
refarea[0].dither_mode = C.EPDC_FLAG_USE_DITHERING_ORDERED
if waveform_mode == C.WAVEFORM_MODE_DU then
refarea[0].quant_bit = 1;
else
refarea[0].quant_bit = 7;
end
else
refarea[0].dither_mode = C.EPDC_FLAG_USE_DITHERING_PASSTHROUGH
refarea[0].quant_bit = 0;
end
-- Enable the appropriate flag when requesting what amounts to a 2bit update, provided we're not dithering.
if waveform_mode == C.WAVEFORM_MODE_DU and not dither then
refarea[0].flags = C.EPDC_FLAG_FORCE_MONOCHROME
else
refarea[0].flags = 0
Expand All @@ -359,7 +368,7 @@ local function refresh_zelda(fb, refreshtype, waveform_mode, x, y, w, h)
return mxc_update(fb, C.MXCFB_SEND_UPDATE_ZELDA, refarea, refreshtype, waveform_mode, x, y, w, h)
end

local function refresh_rex(fb, refreshtype, waveform_mode, x, y, w, h)
local function refresh_rex(fb, refreshtype, waveform_mode, x, y, w, h, dither)
local refarea = ffi.new("struct mxcfb_update_data_rex[1]")
-- only for Amazon's driver, try to mostly follow what the stock reader does...
if waveform_mode == C.WAVEFORM_MODE_ZELDA_GLR16 then
Expand All @@ -372,11 +381,20 @@ local function refresh_rex(fb, refreshtype, waveform_mode, x, y, w, h)
end
-- NOTE: Since there's no longer a distinction between GC16_FAST & GC16, we're done!
refarea[0].temp = C.TEMP_USE_AMBIENT
-- NOTE: Dithering appears to behave differently than on Kobo, so, forget about it until someone with the device cares enough...
refarea[0].dither_mode = C.EPDC_FLAG_USE_DITHERING_PASSTHROUGH
refarea[0].quant_bit = 0;
-- Enable the appropriate flag when requesting what amounts to a 2bit update
if waveform_mode == C.WAVEFORM_MODE_DU then
-- Did we request HW dithering?
if dither then
refarea[0].dither_mode = C.EPDC_FLAG_USE_DITHERING_ORDERED
if waveform_mode == C.WAVEFORM_MODE_DU then
refarea[0].quant_bit = 1;
else
refarea[0].quant_bit = 7;
end
else
refarea[0].dither_mode = C.EPDC_FLAG_USE_DITHERING_PASSTHROUGH
refarea[0].quant_bit = 0;
end
-- Enable the appropriate flag when requesting what amounts to a 2bit update, provided we're not dithering.
if waveform_mode == C.WAVEFORM_MODE_DU and not dither then
refarea[0].flags = C.EPDC_FLAG_FORCE_MONOCHROME
else
refarea[0].flags = 0
Expand Down Expand Up @@ -421,10 +439,10 @@ local function refresh_kobo_mk7(fb, refreshtype, waveform_mode, x, y, w, h, dith
refarea[0].dither_mode = C.EPDC_FLAG_USE_DITHERING_PASSTHROUGH
refarea[0].quant_bit = 0;
end
-- Enable the appropriate flag when requesting a 2bit update
-- Enable the appropriate flag when requesting a 2bit update, provided we're not dithering.
-- NOTE: As of right now (FW 4.9.x), WAVEFORM_MODE_GLD16 appears not to be used by Nickel,
-- so we don't have to care about EPDC_FLAG_USE_REGAL
if waveform_mode == C.WAVEFORM_MODE_A2 then
if waveform_mode == C.WAVEFORM_MODE_A2 and not dither then
refarea[0].flags = C.EPDC_FLAG_FORCE_MONOCHROME
else
refarea[0].flags = 0
Expand Down Expand Up @@ -567,9 +585,7 @@ function framebuffer:init()

-- NOTE: Devices on the Rex platform essentially use the same driver as the Zelda platform, they're just passing a slightly smaller mxcfb_update_data struct
if isZelda or isRex then
-- FIXME: Someone with the device will have to check if/how HW dithering is supposed to be requested,
-- as the Kobo Mk.7 way doesn't appear to work, at the very least on the PW4 (c.f., #4602)
--self.device.canHWDither = yes
self.device.canHWDither = yes
if isZelda then
self.mech_refresh = refresh_zelda
else
Expand Down