changeset 7274:a88b5721a3be

RT-36375 finishing Monocle Robot screen capture (with changes this time) Reviewed-by: dblaukopf
author ddhill
date Fri, 13 Jun 2014 11:20:51 -0400
parents 65903865cab7
children 80be95eb45f1
files modules/graphics/src/main/java/com/sun/glass/ui/monocle/AcceleratedScreen.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/MonocleRobot.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/NativeScreen.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/headless/HeadlessScreen.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/linux/FBDevScreen.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/linux/LinuxFrameBuffer.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/x11/X11Screen.java
diffstat 7 files changed, 155 insertions(+), 26 deletions(-) [+]
line wrap: on
line diff
--- a/modules/graphics/src/main/java/com/sun/glass/ui/monocle/AcceleratedScreen.java	Fri Jun 13 08:41:25 2014 -0700
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/AcceleratedScreen.java	Fri Jun 13 11:20:51 2014 -0400
@@ -126,7 +126,9 @@
     public long getEGLHandle() { return eglLibraryHandle; }
 
     public boolean swapBuffers() {
-        EGL.eglSwapBuffers(eglDisplay, eglSurface);
+        synchronized(NativeScreen.framebufferSwapLock) {
+            EGL.eglSwapBuffers(eglDisplay, eglSurface);
+        }
         return true;
     }
 
--- a/modules/graphics/src/main/java/com/sun/glass/ui/monocle/MonocleRobot.java	Fri Jun 13 08:41:25 2014 -0700
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/MonocleRobot.java	Fri Jun 13 11:20:51 2014 -0400
@@ -32,9 +32,12 @@
 import com.sun.glass.ui.monocle.input.KeyState;
 import com.sun.glass.ui.monocle.input.MouseInput;
 import com.sun.glass.ui.monocle.input.MouseState;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
 import javafx.application.Platform;
 
 import java.nio.IntBuffer;
+import java.nio.ShortBuffer;
 
 public class MonocleRobot extends Robot {
     @Override
@@ -147,28 +150,126 @@
     @Override
     protected int _getPixelColor(int x, int y) {
         NativeScreen screen = NativePlatformFactory.getNativePlatform().getScreen();
-        IntBuffer buffer = screen.getScreenCapture();
-        return buffer.get(x + y * screen.getWidth());
+        final int byteDepth = screen.getDepth() >>> 3;
+        final int bwidth = screen.getWidth();
+        final int bheight = screen.getHeight();
+
+        if (x < 0 || x > bwidth || y < 0 || y > bheight) {
+            return 0;
+        }
+
+        synchronized (NativeScreen.framebufferSwapLock) {
+
+            ByteBuffer buffer = screen.getScreenCapture();
+
+            if (byteDepth == 2) {
+                ShortBuffer shortbuf = buffer.asShortBuffer();
+
+                int v = shortbuf.get((y * bwidth) + x);
+                int red = (int) ((v & 0xF800) >> 11) << 3;
+                int green = (int) ((v & 0x7E0) >> 5) << 2;
+                int blue = (int) (v & 0x1F) << 3;
+
+                int p = (0xff000000
+                        | (red << 16)
+                        | (green << 8)
+                        | blue);
+                return p;
+            } else if (byteDepth >= 4) {
+                IntBuffer intbuf = buffer.asIntBuffer();
+                return intbuf.get((y * bwidth) + x);
+            } else {
+                throw new RuntimeException("Unknown bit depth");
+            }
+        }
     }
 
     @Override
     protected Pixels _getScreenCapture(int x, int y, int width, int height,
-                                       boolean isHiDPI) {
+            boolean isHiDPI) {
         NativeScreen screen = NativePlatformFactory.getNativePlatform().getScreen();
-        IntBuffer buffer = screen.getScreenCapture();
-        buffer.clear();
-        if (x == 0 && y == 0 && width == screen.getWidth() && height == screen.getHeight()) {
-            return new MonoclePixels(width, height, buffer);
-        } else {
-            IntBuffer selection = IntBuffer.allocate(width * height);
-            for (int i = 0; i < height; i++) {
-                int srcPos = x + (y + i) * screen.getWidth();
-                buffer.limit(srcPos + width);
-                buffer.position(srcPos);
-                selection.put(buffer);
+        final int byteDepth = screen.getDepth() >>> 3;
+        final int bwidth = screen.getWidth();
+        final int bheight = screen.getHeight();
+        IntBuffer ret = null;
+
+        synchronized (NativeScreen.framebufferSwapLock) {
+
+            ByteBuffer buffer = screen.getScreenCapture();
+
+            if (x == 0 && y == 0
+                    && width == screen.getWidth() && height == screen.getHeight()
+                    && byteDepth == 4) {
+                return new MonoclePixels(width, height, buffer.asIntBuffer());
+            } else {
+                int size = width * height;
+                ret = IntBuffer.allocate(size);
+
+                ShortBuffer shortbuf = null;
+                IntBuffer intbuf = null;
+
+                if (byteDepth == 2) {
+                    shortbuf = buffer.asShortBuffer();
+                } else if (byteDepth >= 4) {
+                    intbuf = buffer.asIntBuffer();
+                } else {
+                    throw new RuntimeException("Unknown bit depth");
+                }
+
+                // create a subset of the capture in the return buffer
+                int row, col;
+                for (row = y; row < y + height; row++) {
+                    // stepping through one row at a time.
+
+                    int bufferRowStart = row * bwidth; // first in the screen row
+                    int retRowStart = (row - y) * width; // first in return row
+
+                    ret.position(retRowStart);
+                    if ((row < 0) || (row >= bheight)) {
+                        // off the top or bottom of the window
+                        for (col = 0; col < width; col++) {
+                            ret.put(0xff000000); //black
+                        }
+                    } else {
+                        // in the y body
+
+                        // if off the edge, left
+                        for (col = x; col < 0; col++) {
+                            ret.put(0xff000000); //black
+                        }
+
+                        for (; col < x + width && col < bwidth; col++) {
+                            // get our color from the bytebuffer
+
+                            if (byteDepth == 4) {
+                                ret.put(intbuf.get(bufferRowStart + col));
+                            } else if (byteDepth == 2) {
+                                int v = shortbuf.get(bufferRowStart + col);
+                                int red = (int) ((v & 0xF800) >> 11) << 3;
+                                int green = (int) ((v & 0x7E0) >> 5) << 2;
+                                int blue = (int) (v & 0x1F) << 3;
+
+                                int p = (0xff000000 | 
+                                        (red << 16) | 
+                                        (green << 8) | 
+                                        blue);
+
+                                ret.put(p);
+                            }
+
+                        }
+
+                        // if off the edge right
+                        for (; col < x + width; col++) {
+                            ret.put(0xff000000); //black
+                        }
+
+                    }
+                }
             }
-            selection.clear();
-            return new MonoclePixels(width, height, selection);
+            ret.clear();
+
+            return new MonoclePixels(width, height, ret);
         }
     }
 }
--- a/modules/graphics/src/main/java/com/sun/glass/ui/monocle/NativeScreen.java	Fri Jun 13 08:41:25 2014 -0700
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/NativeScreen.java	Fri Jun 13 11:20:51 2014 -0400
@@ -26,7 +26,7 @@
 package com.sun.glass.ui.monocle;
 
 import java.nio.Buffer;
-import java.nio.IntBuffer;
+import java.nio.ByteBuffer;
 
 public interface NativeScreen {
 
@@ -42,6 +42,15 @@
 
     public void swapBuffers();
 
-    public IntBuffer getScreenCapture();
+    /**
+     * Returns a read-only ByteBuffer in the native pixel format containing the screen contents.
+     * @return ByteBuffer a read-only ByteBuffer containing the screen contents
+     */
+    public ByteBuffer getScreenCapture();
+
+    /**
+     * An Object to lock against when rendering
+     */
+    public static final Object framebufferSwapLock = new Object();
 
 }
--- a/modules/graphics/src/main/java/com/sun/glass/ui/monocle/headless/HeadlessScreen.java	Fri Jun 13 08:41:25 2014 -0700
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/headless/HeadlessScreen.java	Fri Jun 13 11:20:51 2014 -0400
@@ -123,7 +123,7 @@
     }
 
     @Override
-    public IntBuffer getScreenCapture() {
-        return fb.getBuffer().asIntBuffer();
+    public ByteBuffer getScreenCapture() {
+        return fb.getBuffer();
     }
 }
--- a/modules/graphics/src/main/java/com/sun/glass/ui/monocle/linux/FBDevScreen.java	Fri Jun 13 08:41:25 2014 -0700
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/linux/FBDevScreen.java	Fri Jun 13 11:20:51 2014 -0400
@@ -212,8 +212,15 @@
     }
 
     @Override
-    public synchronized IntBuffer getScreenCapture() {
-        getFramebuffer().getBuffer().clear();
-        return getFramebuffer().getBuffer().asIntBuffer();
+    public synchronized ByteBuffer getScreenCapture() {
+        ByteBuffer buffer = getFramebuffer().getBuffer();
+        int start = linuxFB.getNativeOffset();
+        int len = getWidth() * getHeight() * (getDepth() >>> 3);
+        buffer.position(start);
+        buffer.limit(start + len);
+        ByteBuffer ret = buffer.asReadOnlyBuffer();
+        // this is critical, as order is lost
+        ret.order(buffer.order());
+        return ret;
     }
 }
--- a/modules/graphics/src/main/java/com/sun/glass/ui/monocle/linux/LinuxFrameBuffer.java	Fri Jun 13 08:41:25 2014 -0700
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/linux/LinuxFrameBuffer.java	Fri Jun 13 11:20:51 2014 -0400
@@ -95,6 +95,16 @@
         }
     }
 
+    public int getNativeOffset() {
+        int nativeOffsetX = screenInfo.getOffsetX(screenInfo.p);
+        int nativeOffsetY = screenInfo.getOffsetY(screenInfo.p);
+        if (system.ioctl(fd, LinuxSystem.FBIOGET_VSCREENINFO, screenInfo.p) == 0) {
+            nativeOffsetX = screenInfo.getOffsetX(screenInfo.p);
+            nativeOffsetY = screenInfo.getOffsetY(screenInfo.p);
+        }
+        return (nativeOffsetY * width) * byteDepth;
+    }
+
     public int getNextAddress() {
         switch (state) {
             case 1:
--- a/modules/graphics/src/main/java/com/sun/glass/ui/monocle/x11/X11Screen.java	Fri Jun 13 08:41:25 2014 -0700
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/x11/X11Screen.java	Fri Jun 13 11:20:51 2014 -0400
@@ -30,7 +30,7 @@
 import com.sun.glass.ui.monocle.AcceleratedScreen;
 
 import java.nio.Buffer;
-import java.nio.IntBuffer;
+import java.nio.ByteBuffer;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 
@@ -197,7 +197,7 @@
     }
 
     @Override
-    public IntBuffer getScreenCapture() {
+    public ByteBuffer getScreenCapture() {
         return null;
     }
 }