1/*
2 * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26#include <stdlib.h>
27#include <string.h>
28#include <sys/time.h>
29#include <sys/utsname.h>
30#include <sys/types.h>
31#include <errno.h>
32#include <dlfcn.h>
33#include "jni.h"
34#include <jni_util.h>
35#include "jvm_md.h"
36#include "awt_Mlib.h"
37#include "java_awt_image_BufferedImage.h"
38
39static void start_timer(int numsec);
40static void stop_timer(int numsec, int ntimes);
41
42/*
43 * This is called by awt_ImagingLib.initLib() to figure out if we
44 * can use the VIS version of medialib
45 */
46mlib_status awt_getImagingLib(JNIEnv *env, mlibFnS_t *sMlibFns,
47                              mlibSysFnS_t *sMlibSysFns) {
48    int status;
49    jstring jstr = NULL;
50    mlibFnS_t *mptr;
51    void *(*vPtr)();
52    int (*intPtr)();
53    mlib_status (*fPtr)();
54    int i;
55    void *handle = NULL;
56    mlibSysFnS_t tempSysFns;
57    static int s_timeIt = 0;
58    static int s_verbose = 1;
59    mlib_status ret = MLIB_SUCCESS;
60    struct utsname name;
61
62    /*
63     * Find out the machine name. If it is an SUN ultra, we
64     * can use the vis library
65     */
66    if ((uname(&name) >= 0) && (getenv("NO_VIS") == NULL) &&
67        (strncmp(name.machine, "sun4u" , 5) == 0) ||
68        ((strncmp(name.machine, "sun4v" , 5) == 0) &&
69         (getenv("USE_VIS_ON_SUN4V") != NULL)))
70    {
71        handle = dlopen(JNI_LIB_NAME("mlib_image_v"), RTLD_LAZY);
72    }
73
74    if (handle == NULL) {
75        handle = dlopen(JNI_LIB_NAME("mlib_image"), RTLD_LAZY);
76    }
77
78    if (handle == NULL) {
79        if (s_timeIt || s_verbose) {
80            printf ("error in dlopen: %s", dlerror());
81        }
82        return MLIB_FAILURE;
83    }
84
85    /* So, if we are here, then either vis or generic version of
86     * medialib library was sucessfuly loaded.
87     * Let's try to initialize handlers...
88     */
89    if ((tempSysFns.createFP = (MlibCreateFP_t)dlsym(handle,
90                                       "j2d_mlib_ImageCreate")) == NULL) {
91        if (s_timeIt) {
92            printf ("error in dlsym: %s", dlerror());
93        }
94        ret = MLIB_FAILURE;
95    }
96
97    if (ret == MLIB_SUCCESS) {
98        if ((tempSysFns.createStructFP = (MlibCreateStructFP_t)dlsym(handle,
99                                          "j2d_mlib_ImageCreateStruct")) == NULL) {
100            if (s_timeIt) {
101                printf ("error in dlsym: %s", dlerror());
102            }
103            ret = MLIB_FAILURE;
104        }
105    }
106
107    if (ret == MLIB_SUCCESS) {
108        if ((tempSysFns.deleteImageFP = (MlibDeleteFP_t)dlsym(handle,
109                                                 "j2d_mlib_ImageDelete")) == NULL) {
110            if (s_timeIt) {
111                printf ("error in dlsym: %s", dlerror());
112            }
113            ret = MLIB_FAILURE;
114        }
115    }
116
117    /* Set the system functions */
118    if (ret == MLIB_SUCCESS) {
119        *sMlibSysFns = tempSysFns;
120    }
121
122    /* Loop through all of the fns and load them from the next library */
123    mptr = sMlibFns;
124    i = 0;
125    while ((ret == MLIB_SUCCESS) && (mptr[i].fname != NULL)) {
126        fPtr = (mlib_status (*)())dlsym(handle, mptr[i].fname);
127        if (fPtr != NULL) {
128            mptr[i].fptr = fPtr;
129        } else {
130            ret = MLIB_FAILURE;
131        }
132        i++;
133    }
134    if (ret != MLIB_SUCCESS) {
135        dlclose(handle);
136    }
137    return ret;
138}
139
140mlib_start_timer awt_setMlibStartTimer() {
141    return start_timer;
142}
143
144mlib_stop_timer awt_setMlibStopTimer() {
145    return stop_timer;
146}
147
148/***************************************************************************
149 *                          Static Functions                               *
150 ***************************************************************************/
151
152static void start_timer(int numsec)
153{
154    struct itimerval interval;
155
156    interval.it_interval.tv_sec = numsec;
157    interval.it_interval.tv_usec = 0;
158    interval.it_value.tv_sec = numsec;
159    interval.it_value.tv_usec = 0;
160    setitimer(ITIMER_REAL, &interval, 0);
161}
162
163
164static void stop_timer(int numsec, int ntimes)
165{
166    struct itimerval interval;
167    double sec;
168
169    getitimer(ITIMER_REAL, &interval);
170    sec = (((double) (numsec - 1)) - (double) interval.it_value.tv_sec) +
171            (1000000.0 - interval.it_value.tv_usec)/1000000.0;
172    sec = sec/((double) ntimes);
173    printf("%f msec per update\n", sec * 1000.0);
174    interval.it_interval.tv_sec = 0;
175    interval.it_interval.tv_usec = 0;
176    interval.it_value.tv_sec = 0;
177    interval.it_value.tv_usec = 0;
178    setitimer(ITIMER_PROF, &interval, 0);
179}
180