From 66c3b385d8f95cdb874836b450e1bdbc2667d28a Mon Sep 17 00:00:00 2001 From: John Neffenger Date: Wed, 29 Apr 2020 17:28:16 +0000 Subject: [PATCH] 8227425: Add support for e-paper displays on i.MX6 devices Reviewed-by: jvos, kcr --- .../sun/glass/ui/monocle/EPDFrameBuffer.java | 95 ++++++++++--- .../com/sun/glass/ui/monocle/EPDScreen.java | 10 +- .../com/sun/glass/ui/monocle/EPDSettings.java | 131 +++++++++++++++++- .../com/sun/glass/ui/monocle/EPDSystem.java | 26 ++-- .../sun/glass/ui/monocle/FramebufferY8.java | 15 +- .../sun/glass/ui/monocle/EPDSettingsTest.java | 2 +- .../glass/ui/monocle/FramebufferY8Test.java | 2 +- 7 files changed, 236 insertions(+), 45 deletions(-) diff --git a/modules/javafx.graphics/src/main/java/com/sun/glass/ui/monocle/EPDFrameBuffer.java b/modules/javafx.graphics/src/main/java/com/sun/glass/ui/monocle/EPDFrameBuffer.java index 6ce50f38a68..b8d687b303f 100644 --- a/modules/javafx.graphics/src/main/java/com/sun/glass/ui/monocle/EPDFrameBuffer.java +++ b/modules/javafx.graphics/src/main/java/com/sun/glass/ui/monocle/EPDFrameBuffer.java @@ -69,6 +69,11 @@ class EPDFrameBuffer { */ private static final int POWERDOWN_DELAY = 1_000; + /** + * Linux system error: ENOTTY 25 Inappropriate ioctl for device. + */ + private static final int ENOTTY = 25; + private final PlatformLogger logger = Logging.getJavaFXLogger(); private final EPDSettings settings; private final LinuxSystem system; @@ -296,6 +301,16 @@ private MxcfbUpdateData createDefaultUpdate(int width, int height) { *
  • {@link EPDSystem#WAVEFORM_MODE_A2}
  • * * + * @implNote This method fails on the Kobo Glo HD Model N437 with the error + * ENOTTY (25), "Inappropriate ioctl for device." The driver on that device + * uses an extended structure with four additional integers, changing its + * size and its corresponding request code. This method could use the + * extended structure, but the driver on the Kobo Glo HD ignores it and + * returns immediately, anyway. Furthermore, newer devices support both the + * current structure and the extended one, but define the extra fields in a + * different order. Therefore, simply use the current structure and ignore + * an error of ENOTTY, picking up the default values for any extra fields. + * * @param init the initialization mode for clearing the screen to all white * @param du the direct update mode for changing any gray values to either * all black or all white @@ -308,7 +323,7 @@ private void setWaveformModes(int init, int du, int gc4, int gc8, int gc16, int var modes = new MxcfbWaveformModes(); modes.setModes(modes.p, init, du, gc4, gc8, gc16, gc32); int rc = system.ioctl(fd, driver.MXCFB_SET_WAVEFORM_MODES, modes.p); - if (rc != 0) { + if (rc != 0 && system.errno() != ENOTTY) { logger.severe("Failed setting waveform modes: {0} ({1})", system.getErrorMessage(), system.errno()); } @@ -325,7 +340,7 @@ private void setWaveformModes(int init, int du, int gc4, int gc8, int gc16, int private void setTemperature(int temp) { int rc = driver.ioctl(fd, driver.MXCFB_SET_TEMPERATURE, temp); if (rc != 0) { - logger.severe("Failed setting temperature to {2} °C: {0} ({1})", + logger.severe("Failed setting temperature to {2} degrees Celsius: {0} ({1})", system.getErrorMessage(), system.errno(), temp); } } @@ -421,7 +436,7 @@ private int sendUpdate(MxcfbUpdateData update, int waveformMode) { logger.severe("Failed sending update {2}: {0} ({1})", system.getErrorMessage(), system.errno(), Integer.toUnsignedLong(updateMarker)); } else if (logger.isLoggable(Level.FINER)) { - logger.finer("Sent update: {0} × {1}, waveform {2}, selected {3}, flags 0x{4}, marker {5}", + logger.finer("Sent update: {0} x {1}, waveform {2}, selected {3}, flags 0x{4}, marker {5}", update.getUpdateRegionWidth(update.p), update.getUpdateRegionHeight(update.p), waveformMode, update.getWaveformMode(update.p), Integer.toHexString(update.getFlags(update.p)).toUpperCase(), @@ -482,7 +497,7 @@ private int getPowerdownDelay() { logger.severe("Failed getting power-down delay: {0} ({1})", system.getErrorMessage(), system.errno()); } - return integer.getInteger(integer.p); + return integer.get(integer.p); } /** @@ -571,20 +586,57 @@ ByteBuffer getOffscreenBuffer() { * "QuantumRenderer modifies buffer in use by JavaFX Application Thread" * . */ - int size = xresVirtual * yresVirtual * Integer.SIZE; + int size = xresVirtual * yres * Integer.BYTES; return ByteBuffer.allocateDirect(size); } /** * Creates a new mapping of the Linux frame buffer device into memory. * + * @implNote The virtual y-resolution reported by the device driver can be + * wrong, as shown by the following example on the Kobo Glo HD Model N437 + * which reports 2,304 pixels when the correct value is 1,152 pixels + * (6,782,976 / 5,888). Therefore, this method cannot use the frame buffer + * virtual resolution to calculate its size. + * + *
    {@code
    +     * $ sudo fbset -i
    +     *
    +     * mode "1448x1072-46"
    +     * # D: 80.000 MHz, H: 50.188 kHz, V: 46.385 Hz
    +     * geometry 1448 1072 1472 2304 32
    +     * timings 12500 16 102 4 4 28 2
    +     * rgba 8/16,8/8,8/0,8/24
    +     * endmode
    +     *
    +     * Frame buffer device information:
    +     * Name        : mxc_epdc_fb
    +     * Address     : 0x88000000
    +     * Size        : 6782976
    +     * Type        : PACKED PIXELS
    +     * Visual      : TRUECOLOR
    +     * XPanStep    : 1
    +     * YPanStep    : 1
    +     * YWrapStep   : 0
    +     * LineLength  : 5888
    +     * Accelerator : No
    +     * }
    + * * @return a byte buffer containing the mapping of the Linux frame buffer - * device + * device if successful; otherwise {@code null} */ ByteBuffer getMappedBuffer() { - int size = xresVirtual * yresVirtual * bytesPerPixel; + ByteBuffer buffer = null; + int size = xresVirtual * yres * bytesPerPixel; + logger.fine("Mapping frame buffer: {0} bytes", size); long addr = system.mmap(0l, size, LinuxSystem.PROT_WRITE, LinuxSystem.MAP_SHARED, fd, 0); - return addr == LinuxSystem.MAP_FAILED ? null : C.getC().NewDirectByteBuffer(addr, size); + if (addr == LinuxSystem.MAP_FAILED) { + logger.severe("Failed mapping {2} bytes of frame buffer: {0} ({1})", + system.getErrorMessage(), system.errno(), size); + } else { + buffer = C.getC().NewDirectByteBuffer(addr, size); + } + return buffer; } /** @@ -594,7 +646,13 @@ ByteBuffer getMappedBuffer() { * buffer device */ void releaseMappedBuffer(ByteBuffer buffer) { - system.munmap(C.getC().GetDirectBufferAddress(buffer), buffer.capacity()); + int size = buffer.capacity(); + logger.fine("Unmapping frame buffer: {0} bytes", size); + int rc = system.munmap(C.getC().GetDirectBufferAddress(buffer), size); + if (rc != 0) { + logger.severe("Failed unmapping {2} bytes of frame buffer: {0} ({1})", + system.getErrorMessage(), system.errno(), size); + } } /** @@ -614,26 +672,31 @@ long getNativeHandle() { } /** - * Gets the virtual horizontal resolution of the frame buffer. See the notes - * for the {@linkplain EPDFrameBuffer#EPDFrameBuffer constructor} above. + * Gets the frame buffer width in pixels. See the notes for the + * {@linkplain EPDFrameBuffer#EPDFrameBuffer constructor} above. + * + * @implNote When using an 8-bit, unrotated, and uninverted frame buffer in + * the Y8 pixel format, the Kobo Clara HD Model N249 works only when this + * method returns the visible x-resolution ({@code xres}) instead of the + * normal virtual x-resolution ({@code xresVirtual}). * - * @return the virtual width in pixels + * @return the width in pixels */ int getWidth() { - return xresVirtual; + return settings.getWidthVisible ? xres : xresVirtual; } /** - * Gets the visible vertical resolution of the frame buffer. + * Gets the frame buffer height in pixels. * - * @return the visible height in pixels + * @return the height in pixels */ int getHeight() { return yres; } /** - * Gets the color depth of the frame buffer. + * Gets the frame buffer color depth in bits per pixel. * * @return the color depth in bits per pixel */ diff --git a/modules/javafx.graphics/src/main/java/com/sun/glass/ui/monocle/EPDScreen.java b/modules/javafx.graphics/src/main/java/com/sun/glass/ui/monocle/EPDScreen.java index b1e845ba88b..bf546fb78df 100644 --- a/modules/javafx.graphics/src/main/java/com/sun/glass/ui/monocle/EPDScreen.java +++ b/modules/javafx.graphics/src/main/java/com/sun/glass/ui/monocle/EPDScreen.java @@ -60,7 +60,7 @@ class EPDScreen implements NativeScreen { /** * The density of this screen in pixels per inch. For now, the value is - * hard-coded to the density of a 6-inch display panel with 800 × 600 px at + * hard-coded to the density of a 6-inch display panel with 800 x 600 px at * 167 ppi. */ private static final int DPI = 167; @@ -99,6 +99,8 @@ class EPDScreen implements NativeScreen { width = fbDevice.getWidth(); height = fbDevice.getHeight(); bitDepth = fbDevice.getBitDepth(); + logger.fine("Native screen geometry: {0} px x {1} px x {2} bpp", + width, height, bitDepth); /* * If the Linux frame buffer is configured for 32-bit color, compose @@ -112,8 +114,12 @@ class EPDScreen implements NativeScreen { * display, though, allows us to reuse the same frame buffer region * immediately after sending an update. */ + ByteBuffer mapping = null; if (bitDepth == Integer.SIZE) { - fbMapping = fbDevice.getMappedBuffer(); + mapping = fbDevice.getMappedBuffer(); + } + if (mapping != null) { + fbMapping = mapping; fbChannel = null; } else { Path path = FileSystems.getDefault().getPath(fbPath); diff --git a/modules/javafx.graphics/src/main/java/com/sun/glass/ui/monocle/EPDSettings.java b/modules/javafx.graphics/src/main/java/com/sun/glass/ui/monocle/EPDSettings.java index d6cfb017c5b..a5603760f8c 100644 --- a/modules/javafx.graphics/src/main/java/com/sun/glass/ui/monocle/EPDSettings.java +++ b/modules/javafx.graphics/src/main/java/com/sun/glass/ui/monocle/EPDSettings.java @@ -38,16 +38,128 @@ */ class EPDSettings { + /** + * Sets the frame buffer color depth and pixel format: 8 for 8-bit grayscale + * in the Y8 pixel format, 16 for 16-bit color in the RGB565 pixel format, + * or 32 for 32-bit color in the ARGB32 pixel format. The default is 32. + *

    + * Using the 32-bit format allows JavaFX to render directly into the Linux + * frame buffer and avoid the step of copying and converting each pixel from + * an off-screen composition buffer.

    + * + * @implNote Corresponds to the {@code bits_per_pixel} field of + * {@code fb_var_screeninfo} in linux/fb.h. + */ private static final String BITS_PER_PIXEL = "monocle.epd.bitsPerPixel"; + + /** + * Sets the frame buffer rotation: 0 for unrotated (UR), 1 for 90 degrees + * clockwise (CW), 2 for 180 degrees upside-down (UD), and 3 for 90 degrees + * counter-clockwise (CCW). The default is 0. + *

    + * The unrotated and upside-down settings are in landscape mode, while the + * clockwise and counter-clockwise settings are in portrait.

    + * + * @implNote Corresponds to the {@code rotate} field of + * {@code fb_var_screeninfo} in linux/fb.h. + */ private static final String ROTATE = "monocle.epd.rotate"; - private static final String Y8_INVERTED = "monocle.epd.y8inverted"; + + /** + * Sets an indicator for the frame buffer grayscale value: {@code true} to + * invert the pixels of all updates when using 8-bit grayscale in the Y8 + * pixel format; otherwise {@code false}. The default is {@code false}. + *

    + * The value is ignored when the frame buffer is not set to 8-bit grayscale + * in the Y8 pixel format.

    + * + * @implNote Corresponds to the {@code GRAYSCALE_8BIT_INVERTED} constant in + * linux/mxcfb.h. + */ + private static final String Y8_INVERTED = "monocle.epd.Y8Inverted"; + + /** + * Indicates whether to wait for the previous update to complete before + * sending the next update: {@code true} to avoid waiting and send updates + * as quickly as possible; otherwise {@code false}. The default is + * {@code false}. + *

    + * The number of outstanding updates is limited by the device controller to + * either 16 or 64 concurrent non-colliding updates, depending on the model. + * A value of {@code true} may result in errors if the maximum number of + * concurrent non-colliding updates is exceeded.

    + * + * @implNote Corresponds to the IOCTL call constant + * {@code MXCFB_WAIT_FOR_UPDATE_COMPLETE} in linux/mxcfb.h. + */ private static final String NO_WAIT = "monocle.epd.noWait"; + + /** + * Sets the waveform mode used for updates: 1 for black-and-white direct + * update (DU), 2 for 16 levels of gray (GC16), 3 for 4 levels of gray + * (GC4), 4 for pure black-and-white animation (A2), and 257 for the + * automatic selection of waveform mode based on the number of gray levels + * in the update (AUTO). The default is 257. + *

    + * Automatic selection chooses one of 1 (DU), 2 (GC16), or 3 (GC4). If the + * waveform mode is set to 2 (GC16), it may be upgraded to a compatible but + * optimized mode internal to the driver, if available.

    + * + * @implNote Corresponds to the {@code waveform_mode} field of + * {@code mxcfb_update_data} in linux/mxcfb.h. + */ private static final String WAVEFORM_MODE = "monocle.epd.waveformMode"; + + /** + * Sets the update flag for pixel inversion: {@code true} to invert the + * pixels of each update; otherwise {@code false}. The default is + * {@code false}. + * + * @implNote Corresponds to the {@code EPDC_FLAG_ENABLE_INVERSION} constant + * in linux/mxcfb.h. + */ private static final String FLAG_ENABLE_INVERSION = "monocle.epd.enableInversion"; + + /** + * Sets the update flag for monochrome conversion: {@code true} to convert + * the pixels of each update to pure black and white using a 50-percent + * threshold; otherwise {@code false}. The default is {@code false}. + * + * @implNote Corresponds to the {@code EPDC_FLAG_FORCE_MONOCHROME} constant + * in linux/mxcfb.h. + */ private static final String FLAG_FORCE_MONOCHROME = "monocle.epd.forceMonochrome"; + + /** + * Sets the update flag for 1-bit dithering: {@code true} to dither each + * update in an 8-bit Y8 frame buffer to 1-bit black and white, if + * available; otherwise {@code false}. The default is {@code false}. + * + * @implNote Corresponds to the {@code EPDC_FLAG_USE_DITHERING_Y1} constant + * in linux/mxcfb.h. + */ private static final String FLAG_USE_DITHERING_Y1 = "monocle.epd.useDitheringY1"; + + /** + * Sets the update flag for 4-bit dithering: {@code true} to dither each + * update in an 8-bit Y8 frame buffer to 4-bit grayscale, if available; + * otherwise {@code false}. The default is {@code false}. + * + * @implNote Corresponds to the {@code EPDC_FLAG_USE_DITHERING_Y4} constant + * in linux/mxcfb.h. + */ private static final String FLAG_USE_DITHERING_Y4 = "monocle.epd.useDitheringY4"; + /** + * Indicates whether to work around the bug found on devices, such as the + * Kobo Clara HD Model N249, which require a screen width equal to the + * visible x-resolution, instead of the normal virtual x-resolution, when + * using an 8-bit, unrotated, and uninverted frame buffer in the Y8 pixel + * format: {@code true} to work around the bug; otherwise {@code false}. The + * default is {@code false}. + */ + private static final String FIX_WIDTH_Y8UR = "monocle.epd.fixWidthY8UR"; + private static final String[] EPD_PROPERTIES = { BITS_PER_PIXEL, ROTATE, @@ -57,7 +169,8 @@ class EPDSettings { FLAG_ENABLE_INVERSION, FLAG_FORCE_MONOCHROME, FLAG_USE_DITHERING_Y1, - FLAG_USE_DITHERING_Y4 + FLAG_USE_DITHERING_Y4, + FIX_WIDTH_Y8UR }; private static final int BITS_PER_PIXEL_DEFAULT = Integer.SIZE; @@ -103,6 +216,7 @@ static EPDSettings newInstance() { private final boolean flagForceMonochrome; private final boolean flagUseDitheringY1; private final boolean flagUseDitheringY4; + private final boolean fixWidthY8UR; final int bitsPerPixel; final int rotate; @@ -110,6 +224,7 @@ static EPDSettings newInstance() { final int waveformMode; final int grayscale; final int flags; + final boolean getWidthVisible; /** * Creates a new EPDSettings, capturing the current values of the EPD system @@ -117,7 +232,7 @@ static EPDSettings newInstance() { */ private EPDSettings() { if (logger.isLoggable(Level.FINE)) { - var map = new HashMap(); + HashMap map = new HashMap<>(); for (String key : EPD_PROPERTIES) { String value = System.getProperty(key); if (value != null) { @@ -151,6 +266,10 @@ private EPDSettings() { | (flagForceMonochrome ? EPDSystem.EPDC_FLAG_FORCE_MONOCHROME : 0) | (flagUseDitheringY1 ? EPDSystem.EPDC_FLAG_USE_DITHERING_Y1 : 0) | (flagUseDitheringY4 ? EPDSystem.EPDC_FLAG_USE_DITHERING_Y4 : 0); + + fixWidthY8UR = Boolean.getBoolean(FIX_WIDTH_Y8UR); + getWidthVisible = fixWidthY8UR && grayscale == EPDSystem.GRAYSCALE_8BIT + && rotate == EPDSystem.FB_ROTATE_UR; } /** @@ -179,8 +298,10 @@ private int getInteger(String key, int def, int... list) { @Override public String toString() { return MessageFormat.format("{0}[bitsPerPixel={1} rotate={2} " - + "noWait={3} waveformMode={4} grayscale={5} flags=0x{6}]", + + "noWait={3} waveformMode={4} grayscale={5} flags=0x{6} " + + "getWidthVisible={7}]", getClass().getName(), bitsPerPixel, rotate, - noWait, waveformMode, grayscale, Integer.toHexString(flags)); + noWait, waveformMode, grayscale, Integer.toHexString(flags), + getWidthVisible); } } diff --git a/modules/javafx.graphics/src/main/java/com/sun/glass/ui/monocle/EPDSystem.java b/modules/javafx.graphics/src/main/java/com/sun/glass/ui/monocle/EPDSystem.java index 98346da20a2..d629144ed00 100644 --- a/modules/javafx.graphics/src/main/java/com/sun/glass/ui/monocle/EPDSystem.java +++ b/modules/javafx.graphics/src/main/java/com/sun/glass/ui/monocle/EPDSystem.java @@ -177,7 +177,7 @@ class EPDSystem { static final int FB_POWERDOWN_DISABLE = -1; /** - * Initialization waveform (0x0...0xF → 0xF in ~4000 ms). Clears the screen + * Initialization waveform (0x0...0xF to 0xF in ~4000 ms). Clears the screen * to all white. *

    * "A first exemplary drive scheme provides waveforms that may be used to @@ -189,7 +189,7 @@ class EPDSystem { static final int WAVEFORM_MODE_INIT = 0; /** - * Direct update waveform (0x0...0xF → 0x0 or 0xF in ~260 ms). Changes gray + * Direct update waveform (0x0...0xF to 0x0 or 0xF in ~260 ms). Changes gray * pixels to black or white. *

    * "A second exemplary drive scheme provides waveforms that may be used to @@ -201,7 +201,7 @@ class EPDSystem { static final int WAVEFORM_MODE_DU = 1; /** - * Gray 4-level waveform (0x0...0xF → 0x0, 0x5, 0xA, or 0xF in ~500 ms). + * Gray 4-level waveform (0x0...0xF to 0x0, 0x5, 0xA, or 0xF in ~500 ms). * Supports 2-bit grayscale images and text with lower quality. *

    * "A third exemplary drive scheme provides waveforms that may be used to @@ -214,8 +214,8 @@ class EPDSystem { static final int WAVEFORM_MODE_GC4 = 3; /** - * Gray 16-level waveform (0x0...0xF → 0x0...0xF in ~760 ms). Supports 4-bit - * grayscale images and text with high quality. + * Gray 16-level waveform (0x0...0xF to 0x0...0xF in ~760 ms). Supports + * 4-bit grayscale images and text with high quality. *

    * "A fourth exemplary drive scheme provides waveforms that may be used to * change the display state of a pixel from any initial display state to a @@ -227,7 +227,7 @@ class EPDSystem { static final int WAVEFORM_MODE_GC16 = 2; /** - * Animation waveform (0x0 or 0xF → 0x0 or 0xF in ~120 ms). Provides a fast + * Animation waveform (0x0 or 0xF to 0x0 or 0xF in ~120 ms). Provides a fast * 1-bit black-and-white animation mode of up to eight frames per second. *

    * "A fifth exemplary drive scheme provides waveforms that may be used to @@ -345,9 +345,11 @@ void loadLibrary() { } /** - * Passes an integer parameter by value to the device driver through the - * IOCTL interface. ({@link LinuxSystem#ioctl}, instead, takes a pointer as - * its third parameter, passing its data by reference.) + * Calls the {@code ioctl} system function, passing a write integer + * parameter. This method is more convenient than passing the pointer to an + * {@code IntStructure} with {@link LinuxSystem#ioctl} and can be used when + * the request code is created by {@link LinuxSystem#IOW} for setting an + * integer value. * * @param fd an open file descriptor * @param request a device-dependent request code @@ -358,7 +360,7 @@ void loadLibrary() { native int ioctl(long fd, int request, int value); /** - * A structure for passing an integer by value in an IOCTL call. + * A structure for passing the pointer to an integer in an IOCTL call. */ static class IntStructure extends C.Structure { @@ -379,11 +381,11 @@ int sizeof() { return BYTES; } - int getInteger(long p) { + int get(long p) { return data.get(VALUE); } - void setInteger(long p, int value) { + void set(long p, int value) { data.put(VALUE, value); } } diff --git a/modules/javafx.graphics/src/main/java/com/sun/glass/ui/monocle/FramebufferY8.java b/modules/javafx.graphics/src/main/java/com/sun/glass/ui/monocle/FramebufferY8.java index f6e08af4a9e..ad2e48fe192 100644 --- a/modules/javafx.graphics/src/main/java/com/sun/glass/ui/monocle/FramebufferY8.java +++ b/modules/javafx.graphics/src/main/java/com/sun/glass/ui/monocle/FramebufferY8.java @@ -93,14 +93,15 @@ class FramebufferY8 extends Framebuffer { * which defines the same primaries and white point as the sRGB color space. *

    {@code
          * Simple average:  Y' = (R' + G' + B') / 3
    -     * Rec. 601 (SDTV): Y' = 0.299  × R' + 0.587  × G' + 0.114  × B'
    -     * Rec. 709 (HDTV): Y' = 0.2126 × R' + 0.7152 × G' + 0.0722 × B'
    -     * Rec. 2100 (HDR): Y' = 0.2627 × R' + 0.6780 × G' + 0.0593 × B'
    +     * Rec. 601 (SDTV): Y' = 0.299  * R' + 0.587  * G' + 0.114  * B'
    +     * Rec. 709 (HDTV): Y' = 0.2126 * R' + 0.7152 * G' + 0.0722 * B'
    +     * Rec. 2100 (HDR): Y' = 0.2627 * R' + 0.6780 * G' + 0.0593 * B'
          * }
    * * @implNote Java rounds toward zero when converting a {@code float} to an - * {@code int}, so this method adds 0.5 before the type conversion to round - * to the nearest integer. + * {@code int}. The calculation of luma could be rounded to the nearest + * integer by adding 0.5 before the type conversion, but the extra operation + * seems unnecessary for a display with only 16 levels of gray. * * @param source the source integer buffer in ARGB32 format * @param target the target byte buffer in Y8 format @@ -110,7 +111,7 @@ private void copyNextPixel(IntBuffer source, ByteBuffer target) { int r = (pixel32 >> 16) & 0xFF; int g = (pixel32 >> 8) & 0xFF; int b = pixel32 & 0xFF; - int y = (int) (0.2126f * r + 0.7152f * g + 0.0722f * b + 0.5f); + int y = (int) (0.2126f * r + 0.7152f * g + 0.0722f * b); target.put((byte) y); } @@ -187,7 +188,6 @@ void write(WritableByteChannel out) throws IOException { String msg = MessageFormat.format("byteDepth={0}", byteDepth); logger.severe(msg); throw new IllegalStateException(msg); - } } @@ -247,7 +247,6 @@ void copyToBuffer(ByteBuffer out) { String msg = MessageFormat.format("byteDepth={0}", byteDepth); logger.severe(msg); throw new IllegalStateException(msg); - } } diff --git a/tests/system/src/test/java/test/com/sun/glass/ui/monocle/EPDSettingsTest.java b/tests/system/src/test/java/test/com/sun/glass/ui/monocle/EPDSettingsTest.java index 3197611b512..cdfd36b1e53 100644 --- a/tests/system/src/test/java/test/com/sun/glass/ui/monocle/EPDSettingsTest.java +++ b/tests/system/src/test/java/test/com/sun/glass/ui/monocle/EPDSettingsTest.java @@ -36,7 +36,7 @@ public class EPDSettingsTest { private static final String BITS_PER_PIXEL = "monocle.epd.bitsPerPixel"; private static final String ROTATE = "monocle.epd.rotate"; - private static final String Y8_INVERTED = "monocle.epd.y8inverted"; + private static final String Y8_INVERTED = "monocle.epd.Y8Inverted"; private static final String NO_WAIT = "monocle.epd.noWait"; private static final String WAVEFORM_MODE = "monocle.epd.waveformMode"; private static final String FLAG_ENABLE_INVERSION = "monocle.epd.enableInversion"; diff --git a/tests/system/src/test/java/test/com/sun/glass/ui/monocle/FramebufferY8Test.java b/tests/system/src/test/java/test/com/sun/glass/ui/monocle/FramebufferY8Test.java index 276e9f616b9..0a0877508ff 100644 --- a/tests/system/src/test/java/test/com/sun/glass/ui/monocle/FramebufferY8Test.java +++ b/tests/system/src/test/java/test/com/sun/glass/ui/monocle/FramebufferY8Test.java @@ -190,7 +190,7 @@ private void writeTest(int bitsPerPixel) throws IOException { private void printTime(Object source, String method, long duration) { float msPerFrame = (float) duration / ITERATIONS; System.out.println(String.format( - "Converted %,d frames of %,d × %,d px to RGB565 in %,d ms (%,.0f ms/frame): %s.%s", + "Converted %,d frames of %,d x %,d px to RGB565 in %,d ms (%,.0f ms/frame): %s.%s", ITERATIONS, WIDTH, HEIGHT, duration, msPerFrame, source.getClass().getSuperclass().getSimpleName(), method)); }