00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "main/imports.h"
00030 #include "main/buffers.h"
00031 #include "main/context.h"
00032 #include "main/framebuffer.h"
00033 #include "main/matrix.h"
00034 #include "main/renderbuffer.h"
00035 #include "main/scissor.h"
00036 #include "st_public.h"
00037 #include "st_context.h"
00038 #include "st_cb_fbo.h"
00039 #include "pipe/p_defines.h"
00040 #include "pipe/p_context.h"
00041 #include "pipe/p_inlines.h"
00042
00043
00044 struct st_framebuffer *
00045 st_create_framebuffer( const __GLcontextModes *visual,
00046 enum pipe_format colorFormat,
00047 enum pipe_format depthFormat,
00048 enum pipe_format stencilFormat,
00049 uint width, uint height,
00050 void *private)
00051 {
00052 struct st_framebuffer *stfb = CALLOC_STRUCT(st_framebuffer);
00053 if (stfb) {
00054 int samples = st_get_msaa();
00055
00056 if (visual->sampleBuffers)
00057 samples = visual->samples;
00058
00059 _mesa_initialize_framebuffer(&stfb->Base, visual);
00060
00061 {
00062
00063
00064
00065 struct gl_renderbuffer *rb
00066 = st_new_renderbuffer_fb(colorFormat, samples);
00067 _mesa_add_renderbuffer(&stfb->Base, BUFFER_FRONT_LEFT, rb);
00068 }
00069
00070 if (visual->doubleBufferMode) {
00071 struct gl_renderbuffer *rb
00072 = st_new_renderbuffer_fb(colorFormat, samples);
00073 _mesa_add_renderbuffer(&stfb->Base, BUFFER_BACK_LEFT, rb);
00074 }
00075
00076 if (depthFormat == stencilFormat && depthFormat != PIPE_FORMAT_NONE) {
00077
00078 struct gl_renderbuffer *depthStencilRb
00079 = st_new_renderbuffer_fb(depthFormat, samples);
00080
00081 _mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthStencilRb);
00082 _mesa_add_renderbuffer(&stfb->Base, BUFFER_STENCIL, depthStencilRb);
00083 }
00084 else {
00085
00086
00087 if (visual->depthBits == 32) {
00088
00089 struct gl_renderbuffer *depthRb
00090 = st_new_renderbuffer_fb(depthFormat, samples);
00091 _mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthRb);
00092 }
00093 else if (visual->depthBits == 24) {
00094
00095 struct gl_renderbuffer *depthRb
00096 = st_new_renderbuffer_fb(depthFormat, samples);
00097 _mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthRb);
00098 }
00099 else if (visual->depthBits > 0) {
00100
00101 struct gl_renderbuffer *depthRb
00102 = st_new_renderbuffer_fb(depthFormat, samples);
00103 _mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthRb);
00104 }
00105
00106 if (visual->stencilBits > 0) {
00107
00108 struct gl_renderbuffer *stencilRb
00109 = st_new_renderbuffer_fb(stencilFormat, samples);
00110 _mesa_add_renderbuffer(&stfb->Base, BUFFER_STENCIL, stencilRb);
00111 }
00112 }
00113
00114 if (visual->accumRedBits > 0) {
00115
00116 struct gl_renderbuffer *accumRb
00117 = st_new_renderbuffer_fb(DEFAULT_ACCUM_PIPE_FORMAT, 0);
00118 _mesa_add_renderbuffer(&stfb->Base, BUFFER_ACCUM, accumRb);
00119 }
00120
00121 stfb->Base.Initialized = GL_TRUE;
00122 stfb->InitWidth = width;
00123 stfb->InitHeight = height;
00124 stfb->Private = private;
00125 }
00126 return stfb;
00127 }
00128
00129
00130 void st_resize_framebuffer( struct st_framebuffer *stfb,
00131 uint width, uint height )
00132 {
00133 if (stfb->Base.Width != width || stfb->Base.Height != height) {
00134 GET_CURRENT_CONTEXT(ctx);
00135 if (ctx) {
00136 if (stfb->InitWidth == 0 && stfb->InitHeight == 0) {
00137
00138 stfb->InitWidth = width;
00139 stfb->InitHeight = height;
00140 if (ctx->Viewport.Width <= 1) {
00141
00142 _mesa_set_viewport(ctx, 0, 0, width, height);
00143 _mesa_set_scissor(ctx, 0, 0, width, height);
00144 }
00145 }
00146
00147 _mesa_resize_framebuffer(ctx, &stfb->Base, width, height);
00148
00149 assert(stfb->Base.Width == width);
00150 assert(stfb->Base.Height == height);
00151 }
00152 }
00153 }
00154
00155
00156 void st_unreference_framebuffer( struct st_framebuffer **stfb )
00157 {
00158 _mesa_unreference_framebuffer((struct gl_framebuffer **) stfb);
00159 }
00160
00161
00162
00168 void
00169 st_set_framebuffer_surface(struct st_framebuffer *stfb,
00170 uint surfIndex, struct pipe_surface *surf)
00171 {
00172 static const GLuint invalid_size = 9999999;
00173 struct st_renderbuffer *strb;
00174 GLuint width, height, i;
00175
00176 assert(surfIndex < BUFFER_COUNT);
00177
00178 strb = st_renderbuffer(stfb->Base.Attachment[surfIndex].Renderbuffer);
00179 assert(strb);
00180
00181
00182 pipe_surface_reference( &strb->surface, surf );
00183 pipe_texture_reference( &strb->texture, surf->texture );
00184
00185
00186 strb->Base.Width = surf->width;
00187 strb->Base.Height = surf->height;
00188
00189
00190
00191
00192 width = height = invalid_size;
00193 for (i = 0; i < BUFFER_COUNT; i++) {
00194 if (stfb->Base.Attachment[i].Renderbuffer) {
00195 if (width == invalid_size) {
00196 width = stfb->Base.Attachment[i].Renderbuffer->Width;
00197 height = stfb->Base.Attachment[i].Renderbuffer->Height;
00198 }
00199 else if (width != stfb->Base.Attachment[i].Renderbuffer->Width ||
00200 height != stfb->Base.Attachment[i].Renderbuffer->Height) {
00201
00202 return;
00203 }
00204 }
00205 }
00206
00207 if (width != invalid_size) {
00208
00209
00210
00211 stfb->Base.Width = width;
00212 stfb->Base.Height = height;
00213 }
00214 }
00215
00216
00217
00221 struct pipe_surface *
00222 st_get_framebuffer_surface(struct st_framebuffer *stfb, uint surfIndex)
00223 {
00224 struct st_renderbuffer *strb;
00225
00226 assert(surfIndex <= ST_SURFACE_DEPTH);
00227
00228
00229 assert(ST_SURFACE_FRONT_LEFT == BUFFER_FRONT_LEFT);
00230 assert(ST_SURFACE_BACK_RIGHT == BUFFER_BACK_RIGHT);
00231
00232 strb = st_renderbuffer(stfb->Base.Attachment[surfIndex].Renderbuffer);
00233 if (strb)
00234 return strb->surface;
00235 return NULL;
00236 }
00237
00238 struct pipe_texture *
00239 st_get_framebuffer_texture(struct st_framebuffer *stfb, uint surfIndex)
00240 {
00241 struct st_renderbuffer *strb;
00242
00243 assert(surfIndex <= ST_SURFACE_DEPTH);
00244
00245
00246 assert(ST_SURFACE_FRONT_LEFT == BUFFER_FRONT_LEFT);
00247 assert(ST_SURFACE_BACK_RIGHT == BUFFER_BACK_RIGHT);
00248
00249 strb = st_renderbuffer(stfb->Base.Attachment[surfIndex].Renderbuffer);
00250 if (strb)
00251 return strb->texture;
00252 return NULL;
00253 }
00254
00260 void
00261 st_notify_swapbuffers(struct st_framebuffer *stfb)
00262 {
00263 GET_CURRENT_CONTEXT(ctx);
00264
00265 if (ctx && ctx->DrawBuffer == &stfb->Base) {
00266 st_flush( ctx->st,
00267 PIPE_FLUSH_RENDER_CACHE |
00268 PIPE_FLUSH_SWAPBUFFERS |
00269 PIPE_FLUSH_FRAME,
00270 NULL );
00271 ctx->st->frontbuffer_status = FRONT_STATUS_COPY_OF_BACK;
00272 }
00273 }
00274
00275
00280 void
00281 st_notify_swapbuffers_complete(struct st_framebuffer *stfb)
00282 {
00283 GET_CURRENT_CONTEXT(ctx);
00284
00285 if (ctx && ctx->DrawBuffer == &stfb->Base) {
00286 struct st_renderbuffer *strb;
00287
00288
00289 strb = st_renderbuffer(stfb->Base.Attachment[BUFFER_BACK_LEFT].
00290 Renderbuffer);
00291 if (strb && strb->surface)
00292 strb->surface->status = PIPE_SURFACE_STATUS_UNDEFINED;
00293
00294 strb = st_renderbuffer(stfb->Base.Attachment[BUFFER_BACK_RIGHT].
00295 Renderbuffer);
00296 if (strb && strb->surface)
00297 strb->surface->status = PIPE_SURFACE_STATUS_UNDEFINED;
00298 }
00299 }
00300
00301
00302 void *st_framebuffer_private( struct st_framebuffer *stfb )
00303 {
00304 return stfb->Private;
00305 }
00306