--- old/src/java.desktop/unix/native/libsunwjdga/dgalock.c 2017-08-15 12:14:06.096964258 -0700 +++ /dev/null 2017-08-10 09:28:49.381064065 -0700 @@ -1,533 +0,0 @@ -/* - * 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 -#include /* ioctl */ -#include -#include /* mmap */ -#include -#include - -/* X11 */ -#include - -#include "jni.h" -#include "jvm_md.h" -#include "jdga.h" -#include "jdgadevice.h" - -#include - -#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