Hlavní navigace

Pohled pod kapotu JVM – nízkoúrovňový přístup k framebufferu i bitmapám s využitím knihovny SDLJava

Pavel Tišnovský

V dnešní části seriálu o programovacím jazyce Java i o virtuálním stroji Javy si řekneme, jakým způsobem je možné s využitím knihovny SDLJava přistupovat k obsahu framebufferu i bitmap na úrovni pixelů. Sice se jedná o poměrně pomalé operace, ovšem v některých typech aplikací se jim nemůžeme vyhnout.

Obsah

1. Pohled pod kapotu JVM – nízkoúrovňový přístup k framebufferu i bitmapám s využitím knihovny SDLJava

2. Formát ukládání pixelů ve framebufferu a v bitmapách

3. Třída sdljava.video.SDLPixelFormat

4. Demonstrační příklad SDLTest8 – zobrazení základních informací o framebufferu

5. Spuštění demonstračního příkladu SDLTest8 a ukázka výstupu

6. Demonstrační příklad SDLTest9 – zobrazení základních informací o načtené bitmapě

7. Spuštění demonstračního příkladu SDLTest9 a ukázka výstupu

8. Vlastnosti použitého video systému

9. Demonstrační příklad SDLTest10 – zobrazení informací o video systému

10. Spuštění demonstračního příkladu SDLTest10 a ukázka výstupu

11. Nízkoúrovňový přístup k obsahu framebufferu a bitmap

12. Demonstrační příklad SDLTest11 – negace všech pixelů uložených v bitmapě

13. Repositář se zdrojovými kódy všech čtyř dnešních demonstračních příkladů

14. Odkazy na Internetu

1. Pohled pod kapotu JVM – nízkoúrovňový přístup k framebufferu a bitmapám s využitím knihovny SDLJava

V dnešní části seriálu o programovacím jazyku Java i o virtuálním stroji tohoto jazyka navážeme na předchozí díl, v němž byl mj. vysvětlen způsob načtení bitmap z externích souborů s následným zobrazením (resp. přenosem) těchto bitmap do framebufferu. Pro úplné pochopení vlastností knihovny SDL (verze 1.x) si však ještě musíme ukázat způsoby manipulace s obsahem bitmap a popř. i s obsahem framebufferu. Jedná se o dosti nízkoúrovňové operace, které neoplývají velkou rychlostí, ovšem v některých případech se jim nemůžeme vyhnout. Příkladem může být například grafický editor, v němž je nutné přistupovat k jednotlivým pixelům popř. k jejich barvovým složkám. Knihovna SDLJava zajišťující rozhraní mezi javovskou aplikací a knihovnou SDL samozřejmě tyto operace podporuje, ovšem s několika omezeními, která vyplývají z toho, že v Javě nelze přímo manipulovat s ukazateli použitými v nativních datových strukturách knihovny SDL.

Nejdříve si popíšeme způsoby získání základních informací o libovolné bitmapě či framebufferu, tedy o objektech, které jsou při využití knihovny SDLJava reprezentovány instancemi třídy sdljava.video.SDLSurface. Následně se seznámíme s třídou sdljava.video.SDLPixelFormat, což je obalující třída céčkové datové struktury nazvané SDL_PixelFormat, z níž lze získat všechny informace nutné pro zakódování či dekódování barev na hodnoty ukládané do bitmapy a/nebo do framebufferu. Nesmíme zapomenout ani na třídu sdljava.video.SDLVideoInfo (obalující céčkovou datovou strukturu SDL_VideoInfo) s informacemi o možnostech video systému. V závěrečné části tohoto článku si ukážeme jeden z jednoduchých (ale současně i pomalých) způsobů přístupu k jednotlivým pixelům uloženým v bitmapě. Všechny informace, které se dnes dozvíme, budou opět ukázány na několika demonstračních příkladech.

2. Formát ukládání pixelů ve framebufferu a v bitmapách

V předchozích dvou částech tohoto seriálu jsme se již seznámili se třídou sdljava.video.SDLSurface, jejíž instance reprezentují buď bitmapy nebo framebuffer. Bitmapy je možné načíst z externích souborů s využitím metody sdljava.video.SDLVideo.loadBMP() popř. sdljava.image.SDLImage.load(), nebo lze (pokud je to nutné) bitmapy tvořit programově, tj. konstrukcí prázdné bitmapy s následným nakreslením nějakého obrazce do bitmapy. Pokud je nutno do bitmapy zapisovat či z ní číst jednotlivé pixely, musíme znát následující údaje: rozměry bitmapy, skutečnou délku obrazového řádku a přesný formát uložení pixelů. Pro zjištění těchto údajů lze využít následující čtveřici metod třídy sdljava.video.SDLSurface:

# Metoda Popis
1 int getWidth() vrátí šířku bitmapy, tj. počet viditelných pixelů na obrazovém řádku
2 int getHeight() vrátí výšku bitmapy, tj. počet viditelných obrazových řádků
3 int getPitch() vrátí skutečnou délku obrazového řádku (viz poznámka níže)
4 SDLPixelFormat getFormat() vrátí instanci třídy SDLPixelFormat obsahující všechny informace o způsobu uložení pixelů v bitmapě

Údaje o šířce a výšce bitmapy jsou uváděny v pixelech, zatímco údaj pitch je používán pro adresaci a tudíž je vrácen jako celková délka obrazového řádku uváděná v bajtech. Tento údaj je nutné znát ze dvou důvodů: u některých typů bitmap i u framebufferů je délka obrazového řádku zarovnána například na násobky čtyř, osmi atd. bajtů, a to proto, aby se jednodušeji prováděly blokové přenosy dat. U některých typů framebufferů je jeho „neviditelná“ část využita pro uložení spritů atd., což může znamenat, že hodnota pitch nebude v žádném případě odpovídat šířce bitmapy vynásobené počtem bajtů nutných pro uložení jednoho pixelu. Můžeme si uvést příklad bitmapy/framebufferu s šířkou 800 pixelů a bitovou hloubkou 32bpp (tj. čtyři bajty na pixel). V tomto případě může hodnota pitch být 800×4=3200 bajtů, ovšem může také být rovna 4096 bajtům atd. Druhý důvod použití hodnoty pitch v praxi spočívá v tom, že se při adresaci pixelů nemusí násobit šířka bitmapy hodnotou bpp (dělitelnou osmi).

3. Třída sdljava.video.SDLPixelFormat

Dalším důležitým údajem o bitmapě a/nebo framebufferu je informace o přesném formátu uložení pixelů. Pro reprezentaci těchto informací se v nativní knihovně SDL používá céčková struktura nazvaná SDL_PixelFormat, která vypadá následovně:

typedef struct SDL_PixelFormat {
    SDL_Palette *palette;
    Uint8  BitsPerPixel;
    Uint8  BytesPerPixel;
    Uint8  Rloss, Gloss, Bloss, Aloss;
    Uint8  Rshift, Gshift, Bshift, Ashift;
    Uint32 Rmask, Gmask, Bmask, Amask;
    Uint32 colorkey;
    Uint8  alpha;
} SDL_PixelFormat;

V knihovně SDLJava je tato datová struktura obalena třídou SDLPixelFormat a najdeme v ní všechny potřebné gettery, které jsou vypsány v následující tabulce:

# Metoda Popis
1 short getRloss() počet bitů, které se ztratí při konverzi hodnoty červené barvové složky v rozsahu 0..255
2 long getRmask() maska, která z hodnoty pixelu odstraní všechny informace kromě červené složky
3 short getRshift() hodnota bitového posunu proto, aby bylo možné získat hodnotu červené složky
4 short getGloss() počet bitů, které se ztratí při konverzi hodnoty zelené barvové složky v rozsahu 0..255
5 long getGmask() maska, která z hodnoty pixelu odstraní všechny informace kromě zelené složky
6 short getGshift() hodnota bitového posunu proto, aby bylo možné získat hodnotu zelené složky
7 short getBloss() počet bitů, které se ztratí při konverzi hodnoty modré barvové složky v rozsahu 0..255
8 long getBmask() maska, která z hodnoty pixelu odstraní všechny informace kromě modré složky
9 short getBshift() hodnota bitového posunu proto, aby bylo možné získat hodnotu modré složky
10 short getAloss() počet bitů, které se ztratí při konverzi hodnoty alfa složky v rozsahu 0..255
11 long getAmask() maska, která z hodnoty pixelu odstraní všechny informace kromě alfa složky
12 short getAshift() hodnota bitového posunu proto, aby bylo možné získat hodnotu alfa složky
13 short getBitsPerPixel() počet bitů, kterými je reprezentovaný pixel
14 short getBytesPerPixel() počet bajtů, kterými je reprezentovaný pixel
15 long getColorkey() klíčová barva (resp. hodnota pixelu), průhledná při operaci typu BitBLT

Význam těchto getterů si zaslouží zvláštní vysvětlení. SDL rozlišuje bitmapy s barvovou paletou a bitmapy bez palety. U bitmap s barvovou paletou má význam pouze zjištění bitové hloubky, tj. jedná se o gettery getBitsPerPixel(), getBytesPerPixel()getColorkey(). Zajímavější je to u bitmap bez palety, které mají většinou bitovou hloubku 16bpp, 24bpp a 32bpp. U těchto bitmap je každá barvová složka (red, green, blue) a popř. i průhlednost pixelu (alfa kanál) uložena ve dvou, třech či čtyřech bajtech a výše popsané gettery #1 až #12 slouží k tomu, aby byl programátor schopen tyto barvové složky získat, popř. naopak ze tří barvových složek (popř. průhlednosti) vypočítat hodnotu pro zápis do bitmapu.

Příkladem může být bitmapa s bitovou hloubkou 24bpp, v níž je každá barvová složka (red, green, blue) reprezentována osmi bity. V tomto případě budou masky jednotlivých barvových složek nastaveny na hodnoty 0×ff000, 0×00ff00 a 0×0000ff a bitové posuny na hodnoty 16, 8 a 0. První barvovou složku (většinou red) získáme maskováním hodnoty pixelu maskou 0×ff0000 a posunem o 16 bitů doprava, druhou barvovou složku (typicky green) maskováním hodnoty pixelu maskou 0×00ff00 a posunem o 8 bitů atd. Hodnota loss je použita v případě, kdy má bitmapa hloubku 16bpp, aby se například pětibitová hodnota získaná maskováním a posunem zkonvertovala na osmibitovou hodnotu.

4. Demonstrační příklad SDLTest8 – zobrazení základních informací o framebufferu

Informace, s nimiž jsme se seznámili v předchozích třech kapitolách, si můžeme ověřit na demonstračním příkladu nazvaném SDLTest8. Po spuštění tohoto demonstračního příkladu se nastaví zvolený video režim (implicitně je použito rozlišení 800×600 pixelů) a následně se zjistí všechny důležité informace jak o rozlišení framebufferu, tak i o hodnotě pitch zmíněné ve druhé kapitole a o formátu uložení pixelů, což bylo téma, kterému jsme se věnovali v kapitole třetí. Všechny zjištěné informace o framebufferu jsou následně vypsány na standardní výstup. Sami si můžete vyzkoušet použití dalších grafických režimů, různých bitových hloubek atd.:

import sdljava.SDLMain;
import sdljava.video.SDLPixelFormat;
import sdljava.video.SDLSurface;
import sdljava.video.SDLVideo;
 
 
 
/**
 * Osmy demonstracni priklad vyuzivajici knihovnu SDLjava.
 *
 * Zobrazeni zakladnich informaci o vybranem grafickem rezimu
 * a o formatu pixelu pouzitych v tomto rezimu.
 *
 * @author Pavel Tisnovsky
 */
public class SDLTest8 {
 
    /**
     * Horizontalni rozliseni vybraneho grafickeho rezimu.
     */
    private static final int GFX_WIDTH = 800;
 
    /**
     * Vertikalni rozliseni vybraneho grafickeho rezimu.
     */
    private static final int GFX_HEIGHT = 600;
 
    /**
     * Bitova hloubka vybraneho grafickeho rezimu.
     * (0 znamena automaticky vyber, ovsem lze samozrejme pouzit
     * i hodnoty 8, 16, 24 ci 32, podle vlastnosti graficke karty)
     */
    private static final int GFX_BPP = 0;
 
    /**
     * Zobrazeni ziskanych informaci o vybranem grafickem rezimu.
     * 
     * @param pixelFormat
     *            format pixelu
     * @param pitch
     *            skutecna delka obrazoveho radku v bajtech
     * @param width
     *            pocet viditelnych pixelu na obrazovem radku
     * @param height
     *            pocet viditelnych obrazovych radku
     */
    private static void printInfo(SDLPixelFormat pixelFormat, int pitch, int width, int height) {
        print("Width:  " + width);
        print("Height: " + height);
        print("Pitch:  " + pitch);
        print("Bpp:    " + pixelFormat.getBitsPerPixel());
        // informace o cervene barvove slozce
        print("Red:");
        print("    shift: " + pixelFormat.getRShift());
        print("    mask:  0x" + Long.toHexString(pixelFormat.getRMask()));
        print("    loss:  " + pixelFormat.getRLoss());
        // informace o zelene barvove slozce
        print("Green:");
        print("    shift: " + pixelFormat.getGShift());
        print("    mask:  0x" + Long.toHexString(pixelFormat.getGMask()));
        print("    loss:  " + pixelFormat.getGLoss());
        // informace o modre barvove slozce
        print("Blue:");
        print("    shift: " + pixelFormat.getBShift());
        print("    mask:  0x" + Long.toHexString(pixelFormat.getBMask()));
        print("    loss:  " + pixelFormat.getBLoss());
        // informace o alfa kanalu
        print("Alpha:");
        print("    shift: " + pixelFormat.getAShift());
        print("    mask:  0x" + Long.toHexString(pixelFormat.getAMask()));
        print("    loss:  " + pixelFormat.getALoss());
    }
 
    /**
     * Vypis retezce na standardni vystup.
     * 
     * @param string
     *            vypisovany retezec
     */
    private static void print(String string) {
        System.out.println(string);
    }
 
    /**
     * Spusteni osmeho demonstracniho prikladu.
     */
    public static void main(String[] args) {
        // informace o formatu pixelu
        SDLPixelFormat pixelFormat = null;
        // skutecna delka obrazoveho radku
        int pitch = 0;
        // realne rozliseni (viditelna bitmapa)
        int width = 0;
        int height = 0;
 
        try {
            // inicializace video subsystemu knihovny SDL.
            SDLMain.init(SDLMain.SDL_INIT_VIDEO);
            // inicializace celoobrazovkoveho grafickeho rezimu
            final SDLSurface screen = SDLVideo.setVideoMode(GFX_WIDTH, GFX_HEIGHT, GFX_BPP, 0);
            Thread.sleep(500);
            // precteni zakladnich informaci o grafickem rezimu
            pixelFormat = screen.getFormat();
            pitch = screen.getPitch();
            width = screen.getWidth();
            height = screen.getHeight();
            Thread.sleep(500);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        finally {
            // musime obnovit puvodni graficky rezim
            // i v tom pripade, ze nastane nejaka vyjimka
            SDLMain.quit();
        }
        // zobrazit ziskane informace
        printInfo(pixelFormat, pitch, width, height);
    }
 
}

5. Spuštění demonstračního příkladu SDLTest8 a ukázka výstupu

Připomeňme si, jakým způsobem je nutné demonstrační příklady využívající knihovnu SDLJava přeložit a následně spustit. Nesmíme zapomenout uvést cestu k javovské části této knihovny (sdljava.jar) a při spuštění ani k nativní části knihovny (libsdljava.so/sdljava.dll):

Skript pro překlad (Linux):

#!/bin/sh
 
SDL_JAVA_LIBS=./sdljava-0.9.1/lib
 
javac -cp $SDL_JAVA_LIBS/sdljava.jar SDLTest8.java

Skript pro překlad (Microsoft Windows):

set SDL_JAVA_LIBS=.\sdljava-0.9.1\lib
 
javac -cp %SDL_JAVA_LIBS%\sdljava.jar SDLTest8.java

Skript pro spuštění (Linux):

#!/bin/sh
 
SDL_JAVA_LIBS=./sdljava-0.9.1/lib
 
javac -cp $SDL_JAVA_LIBS/sdljava.jar SDLTest8.java

Skript pro spuštění (Microsoft Windows):

set SDL_JAVA_LIBS=.\sdljava-0.9.1\lib
 
java -cp .;%SDL_JAVA_LIBS%\sdljava.jar -Djava.library.path=%SDL_JAVA_LIBS% SDLTest8

Zajímavé jsou výsledky spuštění demonstračního příkladu na různých systémech, popř. s různě nastavenými konstantami GFX_WIDTH, GFX_HEIGHTGFX_BPP.

Spuštění při specifikaci osmibitové hloubky, při níž se používá barvová paleta tudíž masky ani bitové posuny nemají význam:

Width:  800
Height: 600
Pitch:  800
Bpp:    8
Red:
    shift: 0
    mask:  0x0
    loss:  8
Green:
    shift: 0
    mask:  0x0
    loss:  8
Blue:
    shift: 0
    mask:  0x0
    loss:  8
Alpha:
    shift: 0
    mask:  0x0
    loss:  8

Při volbě 16bitové hloubky je zajímavé sledovat hodnotu masky i počty bitů, které se u jednotlivých barvových složek ztratí (3 bity pro červenou složku, 2 bity pro složku zelenou a 3 bity pro složku modrou):

Width:  800
Height: 600
Pitch:  1600
Bpp:    16
Red:
    shift: 11
    mask:  0xf800
    loss:  3
Green:
    shift: 5
    mask:  0x7e0
    loss:  2
Blue:
    shift: 0
    mask:  0x1f
    loss:  3
Alpha:
    shift: 0
    mask:  0x0
    loss:  8

Spuštění při specifikaci 24 bitové hloubky ve skutečnosti na testovaném stroji použilo framebuffer s formátem 32bpp, ovšem alfa kanál je nevyužit (maskován):

Width:  800
Height: 600
Pitch:  2400
Bpp:    24
Red:
    shift: 16
    mask:  0xff0000
    loss:  0
Green:
    shift: 8
    mask:  0xff00
    loss:  0
Blue:
    shift: 0
    mask:  0xff
    loss:  0
Alpha:
    shift: 0
    mask:  0x0
    loss:  8

Skutečná 32bitová hloubka framebufferu:

Width:  800
Height: 600
Pitch:  3200
Bpp:    32
Red:
    shift: 16
    mask:  0xff0000
    loss:  0
Green:
    shift: 8
    mask:  0xff00
    loss:  0
Blue:
    shift: 0
    mask:  0xff
    loss:  0
Alpha:
    shift: 0
    mask:  0x0
    loss:  8

6. Demonstrační příklad SDLTest9 – zobrazení základních informací o načtené bitmapě

Demonstrační příklad SDLTest9 se v mnoha ohledech podobá předchozímu demonstračnímu příkladu SDLTest8, až na ten rozdíl, že se zjistí a následně i zobrazí informace o bitmapě uložené do souboru xscorch.bmp (http://icedtea.classpath­.org/people/ptisnovs/jvm-tools/raw-file/6fe0d3a6edeb/sdljava/im­g/xscorch.bmp) a nikoli informace o framebufferu. Povšimněte si, že v tomto příkladu vůbec není nutné nastavovat grafický režim, protože jedinými operacemi, které je nutné provést, je načtení bitmapy pomocí metody sdljava.video.SDLVideo.loadBMP(), přečtení informací o uložení pixelů v bitmapě přes metodu sdljava.video.SDLSurface.getFormat() a následné volání getterů, jenž jsou v této třídě deklarovány (viz třetí kapitolu s podrobnějším popisem):

import sdljava.SDLMain;
import sdljava.video.SDLPixelFormat;
import sdljava.video.SDLSurface;
import sdljava.video.SDLVideo;
 
 
 
/**
 * Devaty demonstracni priklad vyuzivajici knihovnu SDLjava.
 *
 * Zobrazeni zakladnich informaci o bitmape nactene ze souboru
 * typu BMP (Windows Bitmap).
 *
 * @author Pavel Tisnovsky
 */
public class SDLTest9 {
 
    /**
     * Nazev bitmapy, ktera se ma nacist a nasledne zobrazit.
     */
    private static final String IMAGE_NAME = "xscorch.bmp";
 
    /**
     * Zobrazeni ziskanych informaci o bitmape (surface).
     * 
     * @param pixelFormat
     *            format pixelu
     * @param pitch
     *            skutecna delka obrazoveho radku v bajtech
     * @param width
     *            pocet viditelnych pixelu na jednom radku bitmapy
     * @param height
     *            pocet viditelnych obrazovych radku bitmapy
     */
    private static void printInfo(SDLPixelFormat pixelFormat, int pitch, int width, int height) {
        print("Width:  " + width);
        print("Height: " + height);
        print("Pitch:  " + pitch);
        print("Bpp:    " + pixelFormat.getBitsPerPixel());
        // informace o cervene barvove slozce
        print("Red:");
        print("    shift: " + pixelFormat.getRShift());
        print("    mask:  0x" + Long.toHexString(pixelFormat.getRMask()));
        print("    loss:  " + pixelFormat.getRLoss());
        // informace o zelene barvove slozce
        print("Green:");
        print("    shift: " + pixelFormat.getGShift());
        print("    mask:  0x" + Long.toHexString(pixelFormat.getGMask()));
        print("    loss:  " + pixelFormat.getGLoss());
        // informace o modre barvove slozce
        print("Blue:");
        print("    shift: " + pixelFormat.getBShift());
        print("    mask:  0x" + Long.toHexString(pixelFormat.getBMask()));
        print("    loss:  " + pixelFormat.getBLoss());
        // informace o alfa kanalu
        print("Alpha:");
        print("    shift: " + pixelFormat.getAShift());
        print("    mask:  0x" + Long.toHexString(pixelFormat.getAMask()));
        print("    loss:  " + pixelFormat.getALoss());
    }
 
    /**
     * Vypis retezce na standardni vystup.
     * 
     * @param string
     *            vypisovany retezec
     */
    private static void print(String string) {
        System.out.println(string);
    }
 
    /**
     * Spusteni devateho demonstracniho prikladu.
     */
    public static void main(String[] args) {
        // informace o formatu pixelu
        SDLPixelFormat pixelFormat = null;
        // skutecna delka obrazoveho radku
        int pitch = 0;
        // realne rozliseni nactene bitmapy
        int width = 0;
        int height = 0;
 
        try {
            // inicializace video subsystemu knihovny SDL.
            SDLMain.init(SDLMain.SDL_INIT_VIDEO);
            // nacteni bitmapy z externiho souboru
            final SDLSurface bitmap = SDLVideo.loadBMP(IMAGE_NAME);
            // ziskani informaci o nactene bitmape
            pixelFormat = bitmap.getFormat();
            pitch = bitmap.getPitch();
            width = bitmap.getWidth();
            height = bitmap.getHeight();
            Thread.sleep(100);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        finally {
            // musime obnovit puvodni graficky rezim
            // i v tom pripade, ze nastane nejaka vyjimka
            SDLMain.quit();
        }
        // zobrazit ziskane informace
        printInfo(pixelFormat, pitch, width, height);
    }
 
}

7. Spuštění demonstračního příkladu SDLTest9 a ukázka výstupu

Překlad i spuštění příkladu SDLTest9 se provádí naprosto stejným způsobem, jako tomu bylo u předchozího příklad:

Skript pro překlad (Linux):

#!/bin/sh
 
SDL_JAVA_LIBS=./sdljava-0.9.1/lib
 
javac -cp $SDL_JAVA_LIBS/sdljava.jar SDLTest9.java

Skript pro překlad (Microsoft Windows):

set SDL_JAVA_LIBS=.\sdljava-0.9.1\lib
 
javac -cp %SDL_JAVA_LIBS%\sdljava.jar SDLTest9.java

Skript pro spuštění (Linux):

#!/bin/sh
 
SDL_JAVA_LIBS=./sdljava-0.9.1/lib
 
javac -cp $SDL_JAVA_LIBS/sdljava.jar SDLTest9.java

Skript pro spuštění (Microsoft Windows):

set SDL_JAVA_LIBS=.\sdljava-0.9.1\lib
 
java -cp .;%SDL_JAVA_LIBS%\sdljava.jar -Djava.library.path=%SDL_JAVA_LIBS% SDLTest9

Po spuštění tohoto příkladu by se na standardním výstupu měla objevit následující zpráva přesně v tom formátu, v jakém je zde uvedena. Povšimněte si zejména absence alfa kanálu, který značí že v této bitmapě (pokud by nebyla provedena její konverze) nelze ukládat poloprůhledné pixely. Hodnota pitch přesně odpovídá šířce bitmapy vynásobené počtem bajtů na pixel:

Width:  300
Height: 195
Pitch:  900
Bpp:    24
Red:
    shift: 16
    mask:  0xff0000
    loss:  0
Green:
    shift: 8
    mask:  0xff00
    loss:  0
Blue:
    shift: 0
    mask:  0xff
    loss:  0
Alpha:
    shift: 0
    mask:  0x0
    loss:  8

8. Vlastnosti použitého video systému

Knihovna SDL dokáže přečíst i vlastnosti použitého video systému. Tyto informace jsou předány v nativní struktuře (bitovém poli) pojmenované SDL_VideoInfo:

typedef struct{
    Uint32 hw_available:1;
    Uint32 wm_available:1;
    Uint32 blit_hw:1;
    Uint32 blit_hw_CC:1;
    Uint32 blit_hw_A:1;
    Uint32 blit_sw:1;
    Uint32 blit_sw_CC:1;
    Uint32 blit_sw_A:1;
    Uint32 blit_fill;
    Uint32 video_mem;
    SDL_PixelFormat *vfmt;
} SDL_VideoInfo;

Tato struktura je v knihovně SDLJava obalena třídou sdljava.video.SDLVideoInfo, v níž jsou deklarovány následující gettery:

# Metoda Popis
1 getHwAvailable() vrací true pokud se bitmapy vytváří ve video paměti
2 getWmAvailable() vrací true pokud je přítomen správce oken (neplatí například pro FB režimy)
3 getVideoMemory() kapacita VRAM (ne vždy dostupný údaj)
4 getBlit_fill() možnosti akcelerace operace typu rectangle fill
5 getBlit_hw_A() možnosti akcelerace operace typu BitBLT s průhledností pixelů (přenos z VRAM)
6 getBlit_hw_CC() možnosti akcelerace operace typu BitBLT s klíčovou (zcela průhlednou) barvou (přenos z VRAM)
7 getBlit_hw() možnosti akcelerace operace typu BitBLT (přenos z VRAM)
8 getBlit_sw_A() možnosti akcelerace operace typu BitBLT s průhledností pixelů (přenos z operační paměti do VRAM)
9 getBlit_sw_CC() možnosti akcelerace operace typu BitBLT s klíčovou (zcela průhlednou) barvou (přenos z operační paměti do VRAM)
10 getBlit_sw() možnosti akcelerace operace typu BitBLT (přenos z operační paměti do VRAM)

9. Demonstrační příklad SDLTest10 – zobrazení informací o video systému

V demonstračním příkladu SDLTest10 je ukázáno, jakým způsobem lze přečíst informace o video systému nainstalovaném na počítači, na němž je tento příklad spuštěn. Povšimněte si, že instanci třídy sdljava.video.SDLVideoInfo popsané v předchozí kapitole lze získat zavoláním statické metody sdljava.video.SDLVideo.get­VideoInfo():

import sdljava.SDLMain;
import sdljava.video.SDLVideo;
import sdljava.video.SDLVideoInfo;
 
 
 
/**
 * Desaty demonstracni priklad vyuzivajici knihovnu SDLjava.
 *
 * Zobrazeni zakladnich informaci o video subsystemu.
 *
 * @author Pavel Tisnovsky
 */
public class SDLTest10 {
 
    /**
     * Zobrazeni ziskanych informaci o video subsystemu.
     * 
     * @param videoInfo
     *            informace o video subsystemu
     */
    private static void printInfo(SDLVideoInfo videoInfo) {
        print("Window manager available:          " + trueFalse(videoInfo.getWmAvailable()));
        print("Hardware surfaces available:       " + trueFalse(videoInfo.getHwAvailable()));
        print("Total video RAM (kB):              " + videoInfo.getVideoMemory());
        print("Accelerated BitBLT (HW):           " + trueFalse(videoInfo.getBlit_hw()));
        print("Accelerated Color key BitBLT (HW): " + trueFalse(videoInfo.getBlit_hw_CC()));
        print("Accelerated Alpha BitBLT (HW):     " + trueFalse(videoInfo.getBlit_hw_A()));
        print("Accelerated BitBLT (SW):           " + trueFalse(videoInfo.getBlit_sw()));
        print("Accelerated Color key BitBLT (SW): " + trueFalse(videoInfo.getBlit_sw_CC()));
        print("Accelerated Alpha BitBLT (SW):     " + trueFalse(videoInfo.getBlit_sw_A()));
        print("Accelerated BitBLT fill:           " + trueFalse(videoInfo.getBlit_fill()));
    }
 
    /**
     * Prevod priznaku na retezec "true" ci "false".
     * 
     * @param flag
     *            priznak
     * @return retezec "true" ci "false"
     */
    private static String trueFalse(long flag) {
        return flag == 0 ? "no" : "yes";
    }
 
    /**
     * Vypis retezce na standardni vystup.
     * 
     * @param string
     *            vypisovany retezec
     */
    private static void print(String string) {
        System.out.println(string);
    }
 
    /**
     * Spusteni desateho demonstracniho prikladu.
     */
    public static void main(String[] args) {
        try {
            // inicializace video subsystemu knihovny SDL.
            SDLMain.init(SDLMain.SDL_INIT_VIDEO);
            // ziskat informace o video subsystemu
            final SDLVideoInfo videoInfo = SDLVideo.getVideoInfo();
            // zobrazit ziskane informace
            printInfo(videoInfo);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        finally {
            // musime obnovit puvodni graficky rezim
            // i v tom pripade, ze nastane nejaka vyjimka
            SDLMain.quit();
        }
    }
 
}

10. Spuštění demonstračního příkladu SDLTest10 a ukázka výstupu

Příklad SDLTest10 se překládá a spouští naprosto stejným způsobem jako oba dva předchozí příklady SDLTest8SDLTest9, proto zde již nejsou příslušné skripty uvedeny. Zajímavější jsou zprávy, které získáme na standardním výstupu. Pro testovaný systém (Linux, X Window + uzavřené ovladače nVidia) se získaly následující výsledky naznačující, že většina klíčových operací prováděných knihovnou SDL není akcelerována:

Window manager available:          yes
Hardware surfaces available:       no
Total video RAM (kB):              0
Accelerated BitBLT (HW):           no
Accelerated Color key BitBLT (HW): no
Accelerated Alpha BitBLT (HW):     no
Accelerated BitBLT (SW):           no
Accelerated Color key BitBLT (SW): no
Accelerated Alpha BitBLT (SW):     no
Accelerated BitBLT fill:           no

11. Nízkoúrovňový přístup k obsahu framebufferu a bitmap

Pro nízkoúrovňový přístup k obsahu framebufferu a/nebo bitmap lze v případě použití knihovny SDL získat přímo ukazatel (pointer), přes nějž je možné přistupovat k jednotlivým pixelům. V Javě a knihovně SDLJava sice tuto možnost nemáme, namísto toho je ovšem obsah bitmapy přístupný ve formě objektu typu java.nio.ByteBuffer. Ovšem ještě předtím, než je možné číst či zapisovat obsah bitmapy, je nutné bitmapu takzvaně uzamknout s využitím metody lockSurface() a následně opět odemnknout metodou unlockSurface(). Tyto metody sice nemusí být volány pro všechny typy bitmap, ovšem při přímém přístupu do framebufferu se jim nevyhneme:

# Metoda Popis
1 boolean lockSurface()
2 void unlockSurface()
3 java.nio.ByteBuffer getPixelData()

Postup při přímém přístupu k obsahu bitmapy/framebufferu je následující:

    private static void updateBitmap(SDLSurface bitmap) throws SDLException {
        bitmap.lockSurface();
        ByteBuffer pixelBuffer = bitmap.getPixelData();
        ... zde je možné pracovat s pixely
        bitmap.unlockSurface();
    }

Pixely se čtou a zapisují v interní podobě, tj. pro jejich převod na hodnoty RGB či RGBA je nutné použít informace získané metodami vysvětlenými v předchozích kapitolách, popř. využít dvojici konverzních funkcí, které však nejsou nijak závratně rychlé.

12. Demonstrační příklad SDLTest11 – negace všech pixelů uložených v bitmapě

Dnešní poslední demonstrační příklad se jmenuje SDLTest11. Po jeho spuštění se načte bitmapa ze souboru xscorch.bmp a následně se vykreslí na obrazovku (do framebufferu). Po přibližně dvou sekundách se získá buffer obsahující hodnoty všech pixelů v bitmapě a následně jsou tyto hodnoty invertovány (to si můžeme dovolit udělat velmi jednoduše, protože bitmapa neobsahuje alfa kanál). Po inverzi všech pixelů se bitmapa opět zobrazí a posléze se uloží do nového souboru s názvem xscorch2.bmp:

Obrázek 1: Originální bitmapa.

Obrázek 2: Bitmapa vytvořená demonstračním příkladem.

import java.nio.ByteBuffer;
 
import sdljava.SDLMain;
import sdljava.SDLException;
import sdljava.video.SDLRect;
import sdljava.video.SDLVideo;
import sdljava.video.SDLSurface;
 
 
 
/**
 * Jedenacty demonstracni priklad vyuzivajici knihovnu SDLjava.
 *
 * Po spusteni se provede prepnuti do grafickeho rezimu 800x600x16
 * Po inicializaci grafickeho rezimu se nacte bitmapa "xscorch.bmp",
 * ktera je upravena (pixel po pixelu).
 * Bitmapa nasledne vykresli na obrazovku operaci typu BitBLT a navic
 * se ulozi do souboru s nazvem "xscorch2.bmp".
 *
 * @author Pavel Tisnovsky
 */
public class SDLTest11 {
 
    /**
     * Horizontalni rozliseni vybraneho grafickeho rezimu.
     */
    private static final int GFX_WIDTH = 800;
 
    /**
     * Vertikalni rozliseni vybraneho grafickeho rezimu.
     */
    private static final int GFX_HEIGHT = 600;
 
    /**
     * Bitova hloubka vybraneho grafickeho rezimu.
     */
    private static final int GFX_BPP = 16;
 
    /**
     * Nazev bitmapy, ktera se ma nacist a nasledne zobrazit.
     */
    private static final String INPUT_IMAGE_NAME = "xscorch.bmp";
 
    /**
     * Nazev vysledne bitmapy.
     */
    private static final String OUTPUT_IMAGE_NAME = "xscorch2.bmp";
 
    /**
     * Vykresleni bitmapy na obrazovku.
     * 
     * @param screen
     *            framebuffer
     * @param bitmap
     *            bitmapa, ktery se ma na obrazovku vykreslit
     */
    private static void drawOnScreen(SDLSurface screen, SDLSurface bitmap) throws SDLException {
        // vypocitat umisteni bitmapy na obrazovce.
        final SDLRect rect = computePositionOnScreen(screen, bitmap);
        // provest operaci typu BitBLT
        bitmap.blitSurface(screen, rect);
        // nutno volat i v pripade, ze neni pouzit double buffering
        screen.updateRect();
        screen.flip();
    }
 
    /**
     * Vypocitat umisteni bitmapy na obrazovce.
     * 
     * @param screen
     *            framebuffer
     * @param bitmap
     *            bitmapa, ktery se ma na obrazovku vykreslit
     * @return obdelnik predstavujici pozici bitmapy na obrazovce
     */
    private static SDLRect computePositionOnScreen(SDLSurface screen, SDLSurface bitmap) {
        // ziskat rozmery obrazovky i bitmapy
        final int screenWidth = screen.getWidth();
        final int screenHeight = screen.getHeight();
        final int bitmapWidth = bitmap.getWidth();
        final int bitmapHeight = bitmap.getHeight();
 
        // vypocitat umisteni bitmapy na obrazovce
        final int x = (screenWidth - bitmapWidth) >> 1;
        final int y = (screenHeight - bitmapHeight) >> 1;
        return new SDLRect(x, y, bitmapWidth, bitmapHeight);
    }
 
    /**
     * Uprava bitmapy na urovni jednotlivych pixelu.
     *
     * @param bitmap
     * @throws SDLException 
     */
    private static void updateBitmap(SDLSurface bitmap) throws SDLException {
        bitmap.lockSurface();
        ByteBuffer pixelBuffer = bitmap.getPixelData();
        // negace barvovych slozek vsech pixelu
        for (int i = 0; i < pixelBuffer.capacity(); i++) {
            pixelBuffer.put(i, (byte) ~pixelBuffer.get(i));
        }
        bitmap.unlockSurface();
    }
 
    /**
     * Spusteni jedenacteho demonstracniho prikladu.
     */
    public static void main(String[] args) {
        try {
            // inicializace video subsystemu knihovny SDL.
            SDLMain.init(SDLMain.SDL_INIT_VIDEO);
            // inicializace celoobrazovkoveho grafickeho rezimu
            final SDLSurface screen = SDLVideo.setVideoMode(GFX_WIDTH, GFX_HEIGHT, GFX_BPP, SDLVideo.SDL_FULLSCREEN);
            // nacteni bitmapy z externiho souboru
            final SDLSurface bitmap = SDLVideo.loadBMP(INPUT_IMAGE_NAME);
            // vykresleni bitmapy na obrazovku
            drawOnScreen(screen, bitmap);
            Thread.sleep(2000);
            // uprava pixelu v bitmape
            updateBitmap(bitmap);
            // vykresleni bitmapy na obrazovku
            drawOnScreen(screen, bitmap);
            Thread.sleep(2000);
            bitmap.saveBMP(OUTPUT_IMAGE_NAME);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        finally {
            // musime obnovit puvodni graficky rezim
            // i v tom pripade, ze nastane nejaka vyjimka
            SDLMain.quit();
        }
    }
 
}

13. Repositář se zdrojovými kódy všech čtyř dnešních demonstračních příkladů

Všechny čtyři dnešní demonstrační příklady byly společně s podpůrnými skripty určenými pro jejich překlad a následné spuštění uloženy do Mercurial repositáře dostupného na adrese http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/. Podobně jako tomu bylo i v předchozích dvou dílech, i ke dnešním příkladům jsou přiloženy skripty využitelné pro jejich překlad a spuštění. Navíc byly přidány i skripty využitelné ve Windows:

# Zdrojový soubor/skript Umístění souboru v repositáři
1 SDLTest8.java http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/20fe0e5daa24/sdlja­va/SDLTest8/SDLTest8.java
2 SDLTest8_compile.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/20fe0e5daa24/sdlja­va/SDLTest8/SDLTest8_compi­le.sh
3 SDLTest8_compile_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/20fe0e5daa24/sdlja­va/SDLTest8/SDLTest8_compi­le_sys.sh
4 SDLTest8_run.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/20fe0e5daa24/sdlja­va/SDLTest8/SDLTest8_run.sh
5 SDLTest8_run_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/20fe0e5daa24/sdlja­va/SDLTest8/SDLTest8_run_sys­.sh
6 SDLTest8_compile.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/20fe0e5daa24/sdlja­va/SDLTest8/SDLTest8_compi­le.bat
7 SDLTest8_run.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/20fe0e5daa24/sdlja­va/SDLTest8/SDLTest8_run.bat
     
8 SDLTest9.java http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/20fe0e5daa24/sdlja­va/SDLTest9/SDLTest9.java
9 SDLTest9_compile.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/20fe0e5daa24/sdlja­va/SDLTest9/SDLTest9_compi­le.sh
10 SDLTest9_compile_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/20fe0e5daa24/sdlja­va/SDLTest9/SDLTest9_compi­le_sys.sh
11 SDLTest9_run.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/20fe0e5daa24/sdlja­va/SDLTest9/SDLTest9_run.sh
12 SDLTest9_run_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/20fe0e5daa24/sdlja­va/SDLTest9/SDLTest9_run_sys­.sh
13 SDLTest9_compile.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/20fe0e5daa24/sdlja­va/SDLTest9/SDLTest9_compi­le.bat
14 SDLTest9_run.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/20fe0e5daa24/sdlja­va/SDLTest9/SDLTest9_run.bat
     
15 SDLTest10.java http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/20fe0e5daa24/sdlja­va/SDLTest10/SDLTest10.ja­va
16 SDLTest10_compile.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/20fe0e5daa24/sdlja­va/SDLTest10/SDLTest10_com­pile.sh
17 SDLTest10_compile_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/20fe0e5daa24/sdlja­va/SDLTest10/SDLTest10_com­pile_sys.sh
18 SDLTest10_run.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/20fe0e5daa24/sdlja­va/SDLTest10/SDLTest10_run­.sh
19 SDLTest10_run_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/20fe0e5daa24/sdlja­va/SDLTest10/SDLTest10_run_sys­.sh
20 SDLTest10_compile.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/20fe0e5daa24/sdlja­va/SDLTest10/SDLTest10_com­pile.bat
21 SDLTest10_run.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/20fe0e5daa24/sdlja­va/SDLTest10/SDLTest10_run­.bat
     
22 SDLTest11.java http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/20fe0e5daa24/sdlja­va/SDLTest11/SDLTest11.ja­va
23 SDLTest11_compile.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/20fe0e5daa24/sdlja­va/SDLTest11/SDLTest11_com­pile.sh
24 SDLTest11_compile_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/20fe0e5daa24/sdlja­va/SDLTest11/SDLTest11_com­pile_sys.sh
25 SDLTest11_run.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/20fe0e5daa24/sdlja­va/SDLTest11/SDLTest11_run­.sh
26 SDLTest11_run_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/20fe0e5daa24/sdlja­va/SDLTest11/SDLTest11_run_sys­.sh
27 SDLTest11_compile.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/20fe0e5daa24/sdlja­va/SDLTest11/SDLTest11_com­pile.bat
28 SDLTest11_run.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/20fe0e5daa24/sdlja­va/SDLTest11/SDLTest11_run­.bat

Pro správnou činnost demonstračních příkladů SDLTest9SDLTest11 je nutné mít v pracovním adresáři uložen i obrázek xscorch.bmp:

14. Odkazy na Internetu

  1. SDL 1.2 Documentation: SDL_Surface
    http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlsurface.html
  2. SDL 1.2 Documentation: SDL_PixelFormat
    http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlpixelformat.html
  3. SDL 1.2 Documentation: SDL_LockSurface
    http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdllocksurface.html
  4. SDL 1.2 Documentation: SDL_UnlockSurface
    http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlunlocksurface.html
  5. SDL 1.2 Documentation: SDL_LoadBMP
    http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlloadbmp.html
  6. SDL 1.2 Documentation: SDL_SaveBMP
    http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlsavebmp.html
  7. SDL 1.2 Documentation: SDL_BlitSurface
    http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlblitsurface.html
  8. SDL 1.2 Documentation: SDL_VideoInfo
    http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlvideoinfo.html
  9. SDL 1.2 Documentation: SDL_GetVideoInfo
    http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlgetvideoinfo.html
  10. Class BufferStrategy
    http://docs.oracle.com/ja­vase/6/docs/api/java/awt/i­mage/BufferStrategy.html
  11. Class Graphics
    http://docs.oracle.com/ja­vase/1.5.0/docs/api/java/aw­t/Graphics.html
  12. Double Buffering and Page Flipping
    http://docs.oracle.com/ja­vase/tutorial/extra/fullscre­en/doublebuf.html
  13. BufferStrategy and BufferCapabilities
    http://docs.oracle.com/ja­vase/tutorial/extra/fullscre­en/bufferstrategy.html
  14. Java:Tutorials:Double Buffering
    http://content.gpwiki.org/in­dex.php/Java:Tutorials:Dou­ble_Buffering
  15. Double buffer in standard Java AWT
    http://www.codeproject.com/Ar­ticles/2136/Double-buffer-in-standard-Java-AWT
  16. Java 2D: Hardware Accelerating – Part 1 – Volatile Images
    http://www.javalobby.org/fo­rums/thread.jspa?threadID=16840&tstar­t=0
  17. Java 2D: Hardware Accelerating – Part 2 – Buffer Strategies
    http://www.javalobby.org/ja­va/forums/t16867.html
  18. How does paintComponent work?
    http://stackoverflow.com/qu­estions/15544549/how-does-paintcomponent-work
  19. A Swing Architecture Overview
    http://www.oracle.com/technet­work/java/architecture-142923.html
  20. Class javax.swing.JComponent
    http://docs.oracle.com/ja­vase/6/docs/api/javax/swin­g/JComponent.html
  21. Class java.awt.Component
    http://docs.oracle.com/ja­vase/6/docs/api/java/awt/Com­ponent.html
  22. Class java.awt.Component.BltBufferStrategy
    http://docs.oracle.com/ja­vase/6/docs/api/java/awt/Com­ponent.BltBufferStrategy.html
  23. Class java.awt.Component.FlipBufferStrategy
    http://docs.oracle.com/ja­vase/6/docs/api/java/awt/Com­ponent.FlipBufferStrategy­.html
  24. Metoda java.awt.Component.isDoubleBuffered()
    http://docs.oracle.com/ja­vase/6/docs/api/java/awt/Com­ponent.html#isDoubleBuffe­red()
  25. Metoda javax.swing.JComponent.is­DoubleBuffered()
    http://docs.oracle.com/ja­vase/6/docs/api/javax/swin­g/JComponent.html#isDouble­Buffered()
  26. Metoda javax.swing.JComponent.set­DoubleBuffered()
    http://docs.oracle.com/ja­vase/6/docs/api/javax/swin­g/JComponent.html#setDouble­Buffered(boolean)
  27. Javadoc – třída GraphicsDevice
    http://docs.oracle.com/ja­vase/7/docs/api/java/awt/Grap­hicsDevice.html
  28. Javadoc – třída GraphicsEnvironment
    http://docs.oracle.com/ja­vase/7/docs/api/java/awt/Grap­hicsEnvironment.html
  29. Javadoc – třída GraphicsConfiguration
    http://docs.oracle.com/ja­vase/7/docs/api/java/awt/Grap­hicsConfiguration.html
  30. Javadoc – třída DisplayMode
    http://docs.oracle.com/ja­vase/7/docs/api/java/awt/Dis­playMode.html
  31. Lesson: Full-Screen Exclusive Mode API
    http://docs.oracle.com/ja­vase/tutorial/extra/fullscre­en/
  32. Full-Screen Exclusive Mode
    http://docs.oracle.com/ja­vase/tutorial/extra/fullscre­en/exclusivemode.html
  33. Display Mode
    http://docs.oracle.com/ja­vase/tutorial/extra/fullscre­en/displaymode.html
  34. Using the Full-Screen Exclusive Mode API in Java
    http://www.developer.com/ja­va/other/article.php/3609776/U­sing-the-Full-Screen-Exclusive-Mode-API-in-Java.htm
  35. Java quick guide: JVM Instruction Set (tabulka všech instrukcí JVM)
    http://www.mobilefish.com/tu­torials/java/java_quickgu­ide_jvm_instruction_set.html
  36. The JVM Instruction Set
    http://mpdeboer.home.xs4a­ll.nl/scriptie/node14.html
  37. MultiMedia eXtensions
    http://softpixel.com/~cwrig­ht/programming/simd/mmx.phpi
  38. SSE (Streaming SIMD Extentions)
    http://www.songho.ca/misc/sse/sse­.html
  39. Timothy A. Chagnon: SSE and SSE2
    http://www.cs.drexel.edu/~tc365/mpi-wht/sse.pdf
  40. Intel corporation: Extending the Worldr's Most Popular Processor Architecture
    http://download.intel.com/techno­logy/architecture/new-instructions-paper.pdf
  41. SIMD architectures:
    http://arstechnica.com/ol­d/content/2000/03/simd.ar­s/
  42. GC safe-point (or safepoint) and safe-region
    http://xiao-feng.blogspot.cz/2008/01/gc-safe-point-and-safe-region.html
  43. Safepoints in HotSpot JVM
    http://blog.ragozin.info/2012/10/sa­fepoints-in-hotspot-jvm.html
  44. Java theory and practice: Synchronization optimizations in Mustang
    http://www.ibm.com/develo­perworks/java/library/j-jtp10185/
  45. How to build hsdis
    http://hg.openjdk.java.net/jdk7/hot­spot/hotspot/file/tip/src/sha­re/tools/hsdis/README
  46. Java SE 6 Performance White Paper
    http://www.oracle.com/technet­work/java/6-performance-137236.html
  47. Lukas Stadler's Blog
    http://classparser.blogspot­.cz/2010/03/hsdis-i386dll.html
  48. How to build hsdis-amd64.dll and hsdis-i386.dll on Windows
    http://dropzone.nfshost.com/hsdis.htm
  49. PrintAssembly
    https://wikis.oracle.com/dis­play/HotSpotInternals/Prin­tAssembly
  50. The Java Virtual Machine Specification: 3.14. Synchronization
    http://docs.oracle.com/ja­vase/specs/jvms/se7/html/jvms-3.html#jvms-3.14
  51. The Java Virtual Machine Specification: 8.3.1.4. volatile Fields
    http://docs.oracle.com/ja­vase/specs/jls/se7/html/jls-8.html#jls-8.3.1.4
  52. The Java Virtual Machine Specification: 17.4. Memory Model
    http://docs.oracle.com/ja­vase/specs/jls/se7/html/jls-17.html#jls-17.4
  53. The Java Virtual Machine Specification: 17.7. Non-atomic Treatment of double and long
    http://docs.oracle.com/ja­vase/specs/jls/se7/html/jls-17.html#jls-17.7
  54. Open Source ByteCode Libraries in Java
    http://java-source.net/open-source/bytecode-libraries
  55. ASM Home page
    http://asm.ow2.org/
  56. Seznam nástrojů využívajících projekt ASM
    http://asm.ow2.org/users.html
  57. ObjectWeb ASM (Wikipedia)
    http://en.wikipedia.org/wi­ki/ObjectWeb_ASM
  58. Java Bytecode BCEL vs ASM
    http://james.onegoodcooki­e.com/2005/10/26/java-bytecode-bcel-vs-asm/
  59. BCEL Home page
    http://commons.apache.org/bcel/
  60. Byte Code Engineering Library (před verzí 5.0)
    http://bcel.sourceforge.net/
  61. Byte Code Engineering Library (verze >= 5.0)
    http://commons.apache.org/pro­per/commons-bcel/
  62. BCEL Manual
    http://commons.apache.org/bcel/ma­nual.html
  63. Byte Code Engineering Library (Wikipedia)
    http://en.wikipedia.org/wiki/BCEL
  64. BCEL Tutorial
    http://www.smfsupport.com/sup­port/java/bcel-tutorial!/
  65. Bytecode Engineering
    http://book.chinaunix.net/spe­cial/ebook/Core_Java2_Volu­me2AF/0131118269/ch13lev1sec6­.html
  66. Bytecode Outline plugin for Eclipse (screenshoty + info)
    http://asm.ow2.org/eclipse/index.html
  67. Javassist
    http://www.jboss.org/javassist/
  68. Byteman
    http://www.jboss.org/byteman
  69. Java programming dynamics, Part 7: Bytecode engineering with BCEL
    http://www.ibm.com/develo­perworks/java/library/j-dyn0414/
  70. The JavaTM Virtual Machine Specification, Second Edition
    http://java.sun.com/docs/bo­oks/jvms/second_edition/html/VMSpec­TOC.doc.html
  71. The class File Format
    http://java.sun.com/docs/bo­oks/jvms/second_edition/html/Clas­sFile.doc.html
  72. javap – The Java Class File Disassembler
    http://docs.oracle.com/ja­vase/1.4.2/docs/tooldocs/win­dows/javap.html
  73. javap-java-1.6.0-openjdk(1) – Linux man page
    http://linux.die.net/man/1/javap-java-1.6.0-openjdk
  74. Using javap
    http://www.idevelopment.in­fo/data/Programming/java/mis­cellaneous_java/Using_javap­.html
  75. Examine class files with the javap command
    http://www.techrepublic.com/ar­ticle/examine-class-files-with-the-javap-command/5815354
  76. aspectj (Eclipse)
    http://www.eclipse.org/aspectj/
  77. Aspect-oriented programming (Wikipedia)
    http://en.wikipedia.org/wi­ki/Aspect_oriented_program­ming
  78. AspectJ (Wikipedia)
    http://en.wikipedia.org/wiki/AspectJ
  79. EMMA: a free Java code coverage tool
    http://emma.sourceforge.net/
  80. Cobertura
    http://cobertura.sourceforge.net/
  81. jclasslib bytecode viewer
    http://www.ej-technologies.com/products/jclas­slib/overview.html
Našli jste v článku chybu?
120na80.cz: 5 nejčastějších mýtů o kondomech

5 nejčastějších mýtů o kondomech

Lupa.cz: Propustili je z Avastu, už po nich sahá ESET

Propustili je z Avastu, už po nich sahá ESET

Vitalia.cz: Taky věříte na pravidlo 5 sekund?

Taky věříte na pravidlo 5 sekund?

Měšec.cz: Sleva na dítě a manželku pro OSVČ je zpět. Ale..

Sleva na dítě a manželku pro OSVČ je zpět. Ale..

Podnikatel.cz: Přehledná titulka, průvodci, responzivita

Přehledná titulka, průvodci, responzivita

Měšec.cz: Kdy vám stát dá na stěhování 50 000 Kč?

Kdy vám stát dá na stěhování 50 000 Kč?

Měšec.cz: U levneELEKTRO.cz už reklamaci nevyřídíte

U levneELEKTRO.cz už reklamaci nevyřídíte

DigiZone.cz: Recenze Westworld: zavraždit a...

Recenze Westworld: zavraždit a...

Podnikatel.cz: Udávání kvůli EET začalo

Udávání kvůli EET začalo

Podnikatel.cz: Snížení DPH na 15 % se netýká všech

Snížení DPH na 15 % se netýká všech

120na80.cz: Pánové, pečujte o svoje přirození a prostatu

Pánové, pečujte o svoje přirození a prostatu

Měšec.cz: Jak vymáhat výživné zadarmo?

Jak vymáhat výživné zadarmo?

Vitalia.cz: Mondelez stahuje rizikovou čokoládu Milka

Mondelez stahuje rizikovou čokoládu Milka

Vitalia.cz: Pamlsková vyhláška bude platit jen na základkách

Pamlsková vyhláška bude platit jen na základkách

Root.cz: Certifikáty zadarmo jsou horší než za peníze?

Certifikáty zadarmo jsou horší než za peníze?

Měšec.cz: Air Bank zruší TOP3 garanci a zdražuje kurzy

Air Bank zruší TOP3 garanci a zdražuje kurzy

Vitalia.cz: Spor o mortadelu: podle Lidlu falšovaná nebyla

Spor o mortadelu: podle Lidlu falšovaná nebyla

Vitalia.cz: Láska na vozíku: Přitažliví jsme pro tzv. pečovatelky

Láska na vozíku: Přitažliví jsme pro tzv. pečovatelky

Vitalia.cz: Když přijdete o oko, přijdete na rok o řidičák

Když přijdete o oko, přijdete na rok o řidičák

Vitalia.cz: Jsou čajové sáčky toxické?

Jsou čajové sáčky toxické?