1 /*
2  * Copyright (c) 2007, 2008, 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 <malloc.h>
27 #include <string.h>
28 
29 #include "ShaderList.h"
30 #include "Trace.h"
31 
32 /**
33  * Creates a new ShaderInfo that wraps the given fragment program handle
34  * and related data and stores it at the front of the provided ShaderList.
35  * If the addition causes the ShaderList to outgrow its defined capacity,
36  * the least-recently used item in the list (including its fragment program
37  * object) will be disposed.
38  */
39 void
ShaderList_AddProgram(ShaderList * programList,jlong programID,jint compType,jint compMode,jint flags)40 ShaderList_AddProgram(ShaderList *programList,
41                       jlong programID,
42                       jint compType, jint compMode, jint flags)
43 {
44     ShaderInfo *info;
45 
46     J2dTraceLn(J2D_TRACE_INFO, "ShaderList_AddProgram");
47 
48     // create new ShaderInfo
49     info = (ShaderInfo *)malloc(sizeof(ShaderInfo));
50     if (info == NULL) {
51         J2dTraceLn(J2D_TRACE_ERROR,
52                    "D3DContext_AddProgram: could not allocate ShaderInfo");
53         return;
54     }
55 
56     // fill in the information
57     info->next = programList->head;
58     info->programID = programID;
59     info->compType = compType;
60     info->compMode = compMode;
61     info->flags = flags;
62 
63     // insert it at the head of the list
64     programList->head = info;
65 
66     // run through the list and see if we need to delete the least
67     // recently used item
68     {
69         int i = 1;
70         ShaderInfo *prev = NULL;
71         ShaderInfo *curr = info->next;
72         while (curr != NULL) {
73             if (i >= programList->maxItems) {
74                 prev->next = NULL;
75                 programList->dispose(curr->programID);
76                 free(curr);
77                 break;
78             }
79             i++;
80             prev = curr;
81             curr = curr->next;
82         }
83     }
84 }
85 
86 /**
87  * Locates a fragment program handle given a list of shader programs
88  * (ShaderInfos), using the provided composite state and flags as search
89  * parameters.  The "flags" parameter is a bitwise-or'd value that helps
90  * differentiate one program for another; the interpretation of this value
91  * varies depending on the type of shader (BufImgOp, Paint, etc) but here
92  * it is only used to find another ShaderInfo with that same "flags" value.
93  * If no matching program can be located, this method returns 0.
94  */
95 jlong
ShaderList_FindProgram(ShaderList * programList,jint compType,jint compMode,jint flags)96 ShaderList_FindProgram(ShaderList *programList,
97                        jint compType, jint compMode, jint flags)
98 {
99     ShaderInfo *prev = NULL;
100     ShaderInfo *info = programList->head;
101 
102     J2dTraceLn(J2D_TRACE_INFO, "ShaderList_FindProgram");
103 
104     while (info != NULL) {
105         if (compType == info->compType &&
106             compMode == info->compMode &&
107             flags == info->flags)
108         {
109             // it's a match: move it to the front of the list (if it's not
110             // there already) and patch up the links
111             if (info != programList->head) {
112                 prev->next = info->next;
113                 info->next = programList->head;
114                 programList->head = info;
115             }
116             return info->programID;
117         }
118         prev = info;
119         info = info->next;
120     }
121     return 0;
122 }
123 
124 /**
125  * Disposes all entries (and their associated shader program objects)
126  * contained in the given ShaderList.
127  */
128 void
ShaderList_Dispose(ShaderList * programList)129 ShaderList_Dispose(ShaderList *programList)
130 {
131     ShaderInfo *info = programList->head;
132 
133     J2dTraceLn(J2D_TRACE_INFO, "ShaderList_Dispose");
134 
135     while (info != NULL) {
136         ShaderInfo *tmp = info->next;
137         programList->dispose(info->programID);
138         free(info);
139         info = tmp;
140     }
141 
142     programList->head = NULL;
143 }
144