|
Java example source code file (dgalock.c)
The dgalock.c Java example source code/* * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ #if sparc /* #define DGA_DEBUG */ #ifdef DGA_DEBUG #define DEBUG_PRINT(x) printf x #else #define DEBUG_PRINT(x) #endif #include <dga/dga.h> #include <unistd.h> /* ioctl */ #include <stdlib.h> #include <sys/mman.h> /* mmap */ #include <sys/visual_io.h> #include <string.h> /* X11 */ #include <X11/Xlib.h> #include "jni.h" #include "jvm_md.h" #include "jdga.h" #include "jdgadevice.h" #include <dlfcn.h> #define min(x, y) ((x) < (y) ? (x) : (y)) #define max(x, y) ((x) > (y) ? (x) : (y)) typedef struct _SolarisDgaLibInfo SolarisDgaLibInfo; struct _SolarisDgaLibInfo { /* The general (non-device specific) information */ unsigned long count; Drawable drawable; Drawable virtual_drawable; /* The device specific memory mapping information */ SolarisJDgaDevInfo *devInfo; SolarisJDgaWinInfo winInfo; }; typedef Bool IsXineramaOnFunc(Display *display); typedef Drawable GetVirtualDrawableFunc(Display *display, Drawable drawable); #define MAX_CACHED_INFO 16 static SolarisDgaLibInfo cachedInfo[MAX_CACHED_INFO]; static jboolean needsSync = JNI_FALSE; #define MAX_FB_TYPES 16 static SolarisJDgaDevInfo devicesInfo[MAX_FB_TYPES]; static IsXineramaOnFunc *IsXineramaOn = NULL; static GetVirtualDrawableFunc GetVirtualDrawableStub; Drawable GetVirtualDrawableStub(Display *display, Drawable drawable) { return drawable; } static GetVirtualDrawableFunc * GetVirtualDrawable = GetVirtualDrawableStub; static void Solaris_DGA_XineramaInit(Display *display) { void * handle = NULL; if (IsXineramaOn == NULL) { handle = dlopen(JNI_LIB_NAME("xinerama"), RTLD_NOW); if (handle != NULL) { void *sym = dlsym(handle, "IsXineramaOn"); IsXineramaOn = (IsXineramaOnFunc *)sym; if (IsXineramaOn != 0 && (*IsXineramaOn)(display)) { sym = dlsym(handle, "GetVirtualDrawable"); if (sym != 0) { GetVirtualDrawable = (GetVirtualDrawableFunc *)sym; } } else { dlclose(handle); } } } } static SolarisJDgaDevInfo * getDevInfo(Dga_drawable dgadraw) { void *handle = 0; struct vis_identifier visid; int fd; char libName[64]; int i; SolarisJDgaDevInfo *curDevInfo = devicesInfo; fd = dga_draw_devfd(dgadraw); if (ioctl(fd, VIS_GETIDENTIFIER, &visid) != 1) { /* check in the devices list */ for (i = 0; (i < MAX_FB_TYPES) && (curDevInfo->visidName); i++, curDevInfo++) { if (strcmp(visid.name, curDevInfo->visidName) == 0) { /* we already have such a device, return it */ return curDevInfo; } } if (i == MAX_FB_TYPES) { /* we're out of slots, return NULL */ return NULL; } strcpy(libName, "libjdga"); strcat(libName, visid.name); strcat(libName,".so"); /* we use RTLD_NOW because of bug 4032715 */ handle = dlopen(libName, RTLD_NOW); if (handle != 0) { JDgaStatus ret = JDGA_FAILED; void *sym = dlsym(handle, "SolarisJDgaDevOpen"); if (sym != 0) { curDevInfo->majorVersion = JDGALIB_MAJOR_VERSION; curDevInfo->minorVersion = JDGALIB_MINOR_VERSION; ret = (*(SolarisJDgaDevOpenFunc *)sym)(curDevInfo); } if (ret == JDGA_SUCCESS) { curDevInfo->visidName = strdup(visid.name); return curDevInfo; } dlclose(handle); } } return NULL; } static int mmap_dgaDev(SolarisDgaLibInfo *libInfo, Dga_drawable dgadraw) { if (!libInfo->devInfo) { libInfo->devInfo = getDevInfo(dgadraw); if (!libInfo->devInfo) { return JDGA_FAILED; } } return (*libInfo->devInfo->function->winopen)(&(libInfo->winInfo)); } static void unmap_dgaDev(SolarisDgaLibInfo *pDevInfo) { DEBUG_PRINT(("winclose() called\n")); (*pDevInfo->devInfo->function->winclose)(&(pDevInfo->winInfo)); } static jboolean Solaris_DGA_Available(Display *display) { Window root; int screen; Dga_drawable dgaDrawable; SolarisJDgaDevInfo * devinfo; /* return true if any screen supports DGA and we have a library for this type of framebuffer */ for (screen = 0; screen < XScreenCount(display); screen++) { root = RootWindow(display, screen); dgaDrawable = XDgaGrabDrawable(display, root); if (dgaDrawable != 0) { devinfo = getDevInfo(dgaDrawable); XDgaUnGrabDrawable(dgaDrawable); if (devinfo != NULL) { return JNI_TRUE; } } } return JNI_FALSE; } static JDgaLibInitFunc Solaris_DGA_LibInit; static JDgaGetLockFunc Solaris_DGA_GetLock; static JDgaReleaseLockFunc Solaris_DGA_ReleaseLock; static JDgaXRequestSentFunc Solaris_DGA_XRequestSent; static JDgaLibDisposeFunc Solaris_DGA_LibDispose; static int firstInitDone = 0; #pragma weak JDgaLibInit = Solaris_DGA_LibInit static JDgaStatus Solaris_DGA_LibInit(JNIEnv *env, JDgaLibInfo *ppInfo) { /* Note: DGA_INIT can be called multiple times according to docs */ DEBUG_PRINT(("DGA_INIT called\n")); DGA_INIT(); if (!Solaris_DGA_Available(ppInfo->display)) { return JDGA_FAILED; } Solaris_DGA_XineramaInit(ppInfo->display); ppInfo->pGetLock = Solaris_DGA_GetLock; ppInfo->pReleaseLock = Solaris_DGA_ReleaseLock; ppInfo->pXRequestSent = Solaris_DGA_XRequestSent; ppInfo->pLibDispose = Solaris_DGA_LibDispose; return JDGA_SUCCESS; } static JDgaStatus Solaris_DGA_GetLock(JNIEnv *env, Display *display, void **dgaDev, Drawable drawable, JDgaSurfaceInfo *pSurface, jint lox, jint loy, jint hix, jint hiy) { SolarisDgaLibInfo *pDevInfo; SolarisDgaLibInfo *pCachedInfo = cachedInfo; int vis; int dlox, dloy, dhix, dhiy; int i; int type, site; unsigned long k; Drawable prev_virtual_drawable = 0; Dga_drawable dgaDrawable; if (*dgaDev) { if (((SolarisDgaLibInfo *)(*dgaDev))->drawable != drawable) { *dgaDev = 0; } } if (*dgaDev == 0) { pCachedInfo = cachedInfo; for (i = 0 ; (i < MAX_CACHED_INFO) && (pCachedInfo->drawable) ; i++, pCachedInfo++) { if (pCachedInfo->drawable == drawable) { *dgaDev = pCachedInfo; break; } } if (*dgaDev == 0) { if (i < MAX_CACHED_INFO) { /* slot can be used for new info */ *dgaDev = pCachedInfo; } else { pCachedInfo = cachedInfo; /* find the least used slot but does not handle an overflow of the counter */ for (i = 0, k = 0xffffffff; i < MAX_CACHED_INFO ; i++, pCachedInfo++) { if (k > pCachedInfo->count) { k = pCachedInfo->count; *dgaDev = pCachedInfo; } pCachedInfo->count = 0; /* reset all counters */ } pCachedInfo = *dgaDev; if (pCachedInfo->winInfo.dgaDraw != 0) { XDgaUnGrabDrawable(pCachedInfo->winInfo.dgaDraw); } pCachedInfo->winInfo.dgaDraw = 0; /* the slot might be used for another device */ pCachedInfo->devInfo = 0; } } } pDevInfo = *dgaDev; pDevInfo->drawable = drawable; prev_virtual_drawable = pDevInfo->virtual_drawable; pDevInfo->virtual_drawable = GetVirtualDrawable(display, drawable); if (pDevInfo->virtual_drawable == NULL) { /* this usually means that the drawable is spanned across screens in xinerama mode - we can't handle this for now */ return JDGA_FAILED; } else { /* check if the drawable has been moved to another screen since last time */ if (pDevInfo->winInfo.dgaDraw != 0 && pDevInfo->virtual_drawable != prev_virtual_drawable) { XDgaUnGrabDrawable(pDevInfo->winInfo.dgaDraw); pDevInfo->winInfo.dgaDraw = 0; } } pDevInfo->count++; if (pDevInfo->winInfo.dgaDraw == 0) { pDevInfo->winInfo.dgaDraw = XDgaGrabDrawable(display, pDevInfo->virtual_drawable); if (pDevInfo->winInfo.dgaDraw == 0) { DEBUG_PRINT(("DgaGrabDrawable failed for 0x%08x\n", drawable)); return JDGA_UNAVAILABLE; } type = dga_draw_type(pDevInfo->winInfo.dgaDraw); if (type != DGA_DRAW_PIXMAP && mmap_dgaDev(pDevInfo, pDevInfo->winInfo.dgaDraw) != JDGA_SUCCESS) { DEBUG_PRINT(("memory map failed for 0x%08x (depth = %d)\n", drawable, dga_draw_depth(pDevInfo->winInfo.dgaDraw))); XDgaUnGrabDrawable(pDevInfo->winInfo.dgaDraw); pDevInfo->winInfo.dgaDraw = 0; return JDGA_UNAVAILABLE; } } else { type = dga_draw_type(pDevInfo->winInfo.dgaDraw); } if (needsSync) { XSync(display, False); needsSync = JNI_FALSE; } dgaDrawable = pDevInfo->winInfo.dgaDraw; DGA_DRAW_LOCK(dgaDrawable, -1); site = dga_draw_site(dgaDrawable); if (type == DGA_DRAW_PIXMAP) { if (site == DGA_SITE_SYSTEM) { pDevInfo->winInfo.mapDepth = dga_draw_depth(dgaDrawable); pDevInfo->winInfo.mapAddr = dga_draw_address(dgaDrawable); dga_draw_bbox(dgaDrawable, &dlox, &dloy, &dhix, &dhiy); pDevInfo->winInfo.mapWidth = dhix; pDevInfo->winInfo.mapHeight = dhiy; if (pDevInfo->winInfo.mapDepth == 8) { pDevInfo->winInfo.mapLineStride = dga_draw_linebytes(dgaDrawable); pDevInfo->winInfo.mapPixelStride = 1; } else { pDevInfo->winInfo.mapLineStride = dga_draw_linebytes(dgaDrawable)/4; pDevInfo->winInfo.mapPixelStride = 4; } } else { XDgaUnGrabDrawable(dgaDrawable); pDevInfo->winInfo.dgaDraw = 0; return JDGA_UNAVAILABLE; } } else { if (site == DGA_SITE_NULL) { DEBUG_PRINT(("zombie drawable = 0x%08x\n", dgaDrawable)); DGA_DRAW_UNLOCK(dgaDrawable); unmap_dgaDev(pDevInfo); XDgaUnGrabDrawable(dgaDrawable); pDevInfo->winInfo.dgaDraw = 0; return JDGA_UNAVAILABLE; } dga_draw_bbox(dgaDrawable, &dlox, &dloy, &dhix, &dhiy); } /* get the screen address of the drawable */ dhix += dlox; dhiy += dloy; DEBUG_PRINT(("window at (%d, %d) => (%d, %d)\n", dlox, dloy, dhix, dhiy)); pSurface->window.lox = dlox; pSurface->window.loy = dloy; pSurface->window.hix = dhix; pSurface->window.hiy = dhiy; /* translate rendering coordinates relative to device bbox */ lox += dlox; loy += dloy; hix += dlox; hiy += dloy; DEBUG_PRINT(("render at (%d, %d) => (%d, %d)\n", lox, loy, hix, hiy)); vis = dga_draw_visibility(dgaDrawable); switch (vis) { case DGA_VIS_UNOBSCURED: pSurface->visible.lox = max(dlox, lox); pSurface->visible.loy = max(dloy, loy); pSurface->visible.hix = min(dhix, hix); pSurface->visible.hiy = min(dhiy, hiy); DEBUG_PRINT(("unobscured vis at (%d, %d) => (%d, %d)\n", pSurface->visible.lox, pSurface->visible.loy, pSurface->visible.hix, pSurface->visible.hiy)); break; case DGA_VIS_PARTIALLY_OBSCURED: { /* * fix for #4305271 * the dga_draw_clipinfo call returns the clipping bounds * in short ints, but use only full size ints for all comparisons. */ short *ptr; int x0, y0, x1, y1; int cliplox, cliploy, cliphix, cliphiy; /* * iterate to find out whether the clipped blit draws to a * single clipping rectangle */ cliplox = cliphix = lox; cliploy = cliphiy = loy; ptr = dga_draw_clipinfo(dgaDrawable); while (*ptr != DGA_Y_EOL) { y0 = *ptr++; y1 = *ptr++; DEBUG_PRINT(("DGA y range loy=%d hiy=%d\n", y0, y1)); if (y0 < loy) { y0 = loy; } if (y1 > hiy) { y1 = hiy; } while (*ptr != DGA_X_EOL) { x0 = *ptr++; x1 = *ptr++; DEBUG_PRINT((" DGA x range lox=%d hix=%d\n", x0, x1)); if (x0 < lox) { x0 = lox; } if (x1 > hix) { x1 = hix; } if (x0 < x1 && y0 < y1) { if (cliploy == cliphiy) { /* First rectangle intersection */ cliplox = x0; cliploy = y0; cliphix = x1; cliphiy = y1; } else { /* Can we merge this rect with previous? */ if (cliplox == x0 && cliphix == x1 && cliploy <= y1 && cliphiy >= y0) { /* X ranges match, Y ranges touch */ /* => absorb the Y ranges together */ cliploy = min(cliploy, y0); cliphiy = max(cliphiy, y1); } else if (cliploy == y0 && cliphiy == y1 && cliplox <= x1 && cliphix >= x0) { /* Y ranges match, X ranges touch */ /* => Absorb the X ranges together */ cliplox = min(cliplox, x0); cliphix = max(cliphix, x1); } else { /* Assertion: any other combination */ /* means non-rectangular intersect */ DGA_DRAW_UNLOCK(dgaDrawable); return JDGA_FAILED; } } } } ptr++; /* advance past DGA_X_EOL */ } DEBUG_PRINT(("DGA drawable fits\n")); pSurface->visible.lox = cliplox; pSurface->visible.loy = cliploy; pSurface->visible.hix = cliphix; pSurface->visible.hiy = cliphiy; break; } case DGA_VIS_FULLY_OBSCURED: pSurface->visible.lox = pSurface->visible.hix = lox; pSurface->visible.loy = pSurface->visible.hiy = loy; DEBUG_PRINT(("fully obscured vis\n")); break; default: DEBUG_PRINT(("unknown visibility = %d!\n", vis)); DGA_DRAW_UNLOCK(dgaDrawable); return JDGA_FAILED; } pSurface->basePtr = pDevInfo->winInfo.mapAddr; pSurface->surfaceScan = pDevInfo->winInfo.mapLineStride; pSurface->surfaceWidth = pDevInfo->winInfo.mapWidth; pSurface->surfaceHeight = pDevInfo->winInfo.mapHeight; pSurface->surfaceDepth = pDevInfo->winInfo.mapDepth; return JDGA_SUCCESS; } static JDgaStatus Solaris_DGA_ReleaseLock(JNIEnv *env, void *dgaDev, Drawable drawable) { SolarisDgaLibInfo *pDevInfo = (SolarisDgaLibInfo *) dgaDev; if (pDevInfo != 0 && pDevInfo->drawable == drawable && pDevInfo->winInfo.dgaDraw != 0) { DGA_DRAW_UNLOCK(pDevInfo->winInfo.dgaDraw); } return JDGA_SUCCESS; } static void Solaris_DGA_XRequestSent(JNIEnv *env, void *dgaDev, Drawable drawable) { needsSync = JNI_TRUE; } static void Solaris_DGA_LibDispose(JNIEnv *env) { SolarisDgaLibInfo *pCachedInfo = cachedInfo; SolarisJDgaDevInfo *curDevInfo = devicesInfo; int i; for (i = 0 ; (i < MAX_CACHED_INFO) && (pCachedInfo->drawable) ; i++, pCachedInfo++) { if (pCachedInfo->winInfo.dgaDraw != 0) { if (dga_draw_type(pCachedInfo->winInfo.dgaDraw) == DGA_DRAW_WINDOW && pCachedInfo->winInfo.mapDepth != 0) { unmap_dgaDev(pCachedInfo); } XDgaUnGrabDrawable(pCachedInfo->winInfo.dgaDraw); pCachedInfo->winInfo.dgaDraw = 0; } } for (i = 0; (i < MAX_FB_TYPES) && (curDevInfo->visidName); i++, curDevInfo++) { curDevInfo->function->devclose(curDevInfo); free(curDevInfo->visidName); } } #endif Other Java examples (source code examples)Here is a short list of links related to this Java dgalock.c source code file: |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.