source: svn/trunk/newcon3bcm2_21bu/nexus/modules/surface/7552/src/nexus_surface.c

Last change on this file was 2, checked in by jglee, 11 years ago

first commit

  • Property svn:executable set to *
File size: 24.2 KB
Line 
1/***************************************************************************
2 *     (c)2007-2011 Broadcom Corporation
3 *
4 *  This program is the proprietary software of Broadcom Corporation and/or its licensors,
5 *  and may only be used, duplicated, modified or distributed pursuant to the terms and
6 *  conditions of a separate, written license agreement executed between you and Broadcom
7 *  (an "Authorized License").  Except as set forth in an Authorized License, Broadcom grants
8 *  no license (express or implied), right to use, or waiver of any kind with respect to the
9 *  Software, and Broadcom expressly reserves all rights in and to the Software and all
10 *  intellectual property rights therein.  IF YOU HAVE NO AUTHORIZED LICENSE, THEN YOU
11 *  HAVE NO RIGHT TO USE THIS SOFTWARE IN ANY WAY, AND SHOULD IMMEDIATELY
12 *  NOTIFY BROADCOM AND DISCONTINUE ALL USE OF THE SOFTWARE.
13 *
14 *  Except as expressly set forth in the Authorized License,
15 *
16 *  1.     This program, including its structure, sequence and organization, constitutes the valuable trade
17 *  secrets of Broadcom, and you shall use all reasonable efforts to protect the confidentiality thereof,
18 *  and to use this information only in connection with your use of Broadcom integrated circuit products.
19 *
20 *  2.     TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
21 *  AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES, REPRESENTATIONS OR
22 *  WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO
23 *  THE SOFTWARE.  BROADCOM SPECIFICALLY DISCLAIMS ANY AND ALL IMPLIED WARRANTIES
24 *  OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE,
25 *  LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION
26 *  OR CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING OUT OF
27 *  USE OR PERFORMANCE OF THE SOFTWARE.
28 *
29 *  3.     TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM OR ITS
30 *  LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL, INDIRECT, OR
31 *  EXEMPLARY DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY WAY RELATING TO YOUR
32 *  USE OF OR INABILITY TO USE THE SOFTWARE EVEN IF BROADCOM HAS BEEN ADVISED OF
33 *  THE POSSIBILITY OF SUCH DAMAGES; OR (ii) ANY AMOUNT IN EXCESS OF THE AMOUNT
34 *  ACTUALLY PAID FOR THE SOFTWARE ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE
35 *  LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF
36 *  ANY LIMITED REMEDY.
37 *
38 * $brcm_Workfile: nexus_surface.c $
39 * $brcm_Revision: 52 $
40 * $brcm_Date: 12/13/11 4:27p $
41 *
42 * Module Description:
43 *
44 * Revision History:
45 *
46 * $brcm_Log: /nexus/modules/surface/7400/src/nexus_surface.c $
47 *
48 * 52   12/13/11 4:27p erickson
49 * SW7420-2129: get current default heap using NEXUS_P_DefaultHeap
50 *
51 * 51   10/7/11 1:49p vsilyaev
52 * SW7420-2085: Added support for object reference counting
53 *
54 * 50   8/26/11 12:43p erickson
55 * SW7420-1575: NEXUS_Surface_CreateFromMagnum_priv must set surface-
56 *  >offset
57 *
58 * 49   5/23/11 1:34p erickson
59 * SW7420-1200: add NEXUS_Surface_InitPlane_priv
60 *
61 * 48   5/19/11 12:42p erickson
62 * SW7422-444: back out last checkin
63 *
64 * 47   5/13/11 2:55p erickson
65 * SW7422-444: add check for fake address to NEXUS_Surface_GetMemory
66 *
67 * 46   3/8/11 5:11p erickson
68 * SW7420-1575: add NEXUS_Surface_InitPlane for packet blit verification
69 *
70 * 45   2/9/11 11:34a vsilyaev
71 * SW7420-1441:Fixed typo
72 *
73 * 44   2/7/11 2:03p vsilyaev
74 * SW7420-1441: Fixed calculations for the size of the surface buffer
75 *
76 * 43   2/3/11 6:37p vsilyaev
77 * SW7420-1441: Use local (non proxied) implementation for function that
78 *  flush CPU cache
79 *
80 * 42   12/7/10 5:44p erickson
81 * SW7420-1148: remove unnecessary memset
82 *
83 * 41   10/22/10 2:47p erickson
84 * SW7420-1205: deprecate NEXUS_SurfaceSettings.autoFlush because of
85 *  inherent performance problems
86 *
87 * 40   8/24/10 4:26p erickson
88 * SW3548-681: downgrade ERR to WRN. this is a legal call in some cases.
89 *
90 * 39   8/6/10 1:08p erickson
91 * SW7420-703: NEXUS_Surface_GetCreateSettings
92 *
93 * 38   7/14/10 12:48p erickson
94 * SW7405-3787: fix alignment units and calc
95 *
96 * 37   6/23/10 12:14p erickson
97 * SW7550-453: add nexus_striped_surface.h interface
98 *
99 * 36   4/21/10 9:27a erickson
100 * SW7420-703: add NEXUS_SurfaceModuleSettings.heapIndex for chips where
101 *  graphics cannot be allocated in MEMC0
102 *
103 * 35   1/18/10 3:14p erickson
104 * SW7405-3787: default nexus surface allocations to 4K alignment to avoid
105 *  stale data in the RAC. also, alignment must apply to both the frontend
106 *  (i.e. the alignment) and the backend (i.e. padding the allocation)
107 *
108 * 34   11/10/09 1:52p nickh
109 * SW7420-166: Remove hard coded heap settings for 7420 and pass them in
110 *  from Brutus/settop layer
111 *
112 * 33   8/21/09 5:14p vsilyaev
113 * PR 57469: Added  trace statements to allow capture exact flow of 2D
114 *  operations
115 *
116 * 32   8/12/09 11:21a vsilyaev
117 * PR 57629: Replaced NEXUS_Surface_AutoFlush_priv with
118 *  NEXUS_Surface_GetSurfaceAutoFlush_priv
119 *
120 * 31   7/29/09 4:13p nickh
121 * PR56017: Add 7420B0 support
122 *
123 * 30   7/13/09 8:16a erickson
124 * PR56673: only memset palette memory if created by nexus
125 *
126 * 29   5/1/09 11:07a jgarrett
127 * PR 54512: Adding prediction mode
128 *
129 * 28   3/31/09 10:05a erickson
130 * PR53661: remove NEXUS_SurfaceSettings.constantColor. it was unused. the
131 *  intended functionality can be accomplished using the constantColor in
132 *  NEXUS_Graphics2DBlitSettings.
133 *
134 * 27   3/24/09 9:41a erickson
135 * PR47583: fix NEXUS_Surface_CreateFromMagnum_priv because of surface
136 *  member additions.
137 *
138 * 26   2/25/09 7:23p nickh
139 * PR52525: Implement SW workaround for 7420 3D graphics demos
140 *
141 * 25   1/30/09 4:26p erickson
142 * PR46300: removed NEXUS_Surface_CreateSpecial
143 *
144 * 24   1/26/09 11:29a erickson
145 * PR51468: global variable naming convention
146 *
147 * 23   1/13/09 6:11p erickson
148 * PR46300: added NEXUS_Surface_CreateSpecial
149 *
150 * 22   12/30/08 9:20a erickson
151 * PR50743: implement NEXUS_SurfaceCreateSettings.pPaletteMemory. return
152 *  cached address for palette and implement palette flush.
153 *
154 * 21   12/23/08 5:09p nickh
155 * PR48963: Create surfaces from MEMC1 heap for 7420
156 *
157 * 20   12/17/08 11:59p erickson
158 * PR50438: NEXUS_Surface_Destroy should handle case where no surface-
159 *  >buffer exists
160 *
161 * 19   11/26/08 9:59a erickson
162 * PR49649: added NEXUS_SurfaceCreateSettings.heap option
163 *
164 * 18   11/7/08 9:43a erickson
165 * PR46300: moved NEXUS_Surface to module.h to allow for extension
166 *
167 * 17   10/31/08 10:16a jtna
168 * PR48586: initialize surface->mem.numPaletteEntries = 0 for non-palette
169 *  pixel formats
170 *
171 * 16   10/1/08 4:48p erickson
172 * PR47303: BSUR_Surface_Create api change
173 *
174 * 15   9/25/08 10:57a erickson
175 * PR47313: fix assignment of height
176 *
177 * 14   9/18/08 4:17p erickson
178 * PR47111: free memory on error case
179 *
180 * 13   8/28/08 10:42a erickson
181 * PR46111: add palettePixelFormat
182 *
183 * 12   8/21/08 5:14p erickson
184 * PR45941: added NEXUS_StripedSurface_GetStatus
185 *
186 * 11   8/14/08 5:25p katrep
187 * PR45674: Fix compiiler warning in kernel mode non debug builds
188 *
189 * 10   5/5/08 2:54p erickson
190 * PR40777: handle interlaced stills using M2MC, not software
191 *
192 * 9   3/31/08 1:41p erickson
193 * PR41077: added NEXUS_ASSERT_MODULE to _priv function
194 *
195 * 8   3/26/08 12:51p erickson
196 * PR40567: use Core conversion functions for pixel format
197 *
198 * 7   3/19/08 12:32p erickson
199 * PR40307: change NEXUS_Surface_ProcessAsField_priv factor to 4 until
200 *  M2MC chroma upsample can be fixed
201 *
202 * 6   3/14/08 10:10a erickson
203 * PR40307: 40316
204 *
205 * 5   2/20/08 9:51a erickson
206 * PR39771: check return code
207 *
208 * 4   2/8/08 11:40a vsilyaev
209 * PR 38396: Fixed warning
210 *
211 * 3   1/29/08 3:36p jgarrett
212 * PR 38396: Fixing externally allocated surface memory
213 *
214 * 3   1/29/08 3:33p jgarrett
215 * PR 38396: Fixing externally allocated surface memory
216 *
217 * 2   1/28/08 1:00p vsilyaev
218 * PR 38682: Initialize palette address to NULL
219 *
220 * 1   1/18/08 2:19p jgarrett
221 * PR 38808: Merging to main branch
222 *
223 **************************************************************************/
224#include "nexus_surface_module.h"
225#include "priv/nexus_core.h"
226#include "priv/nexus_core_video.h"
227
228BDBG_MODULE(nexus_surface);
229
230#define BDBG_MSG_TRACE(x) /* BDBG_MSG(x) */
231
232/* global instances */
233NEXUS_ModuleHandle g_NEXUS_surfaceModule;
234static struct NEXUS_SurfaceModuleData {
235    NEXUS_SurfaceModuleSettings settings;
236} g_NEXUS_SurfaceModuleData;
237
238BDBG_OBJECT_ID(NEXUS_Surface);
239
240
241void NEXUS_SurfaceModule_GetDefaultSettings(NEXUS_SurfaceModuleSettings *pSettings)
242{
243    BKNI_Memset(pSettings, 0, sizeof(*pSettings));
244}
245
246NEXUS_ModuleHandle NEXUS_SurfaceModule_Init(const NEXUS_SurfaceModuleSettings *pSettings)
247{
248    NEXUS_ModuleSettings moduleSettings;
249
250    BDBG_ASSERT(!g_NEXUS_surfaceModule);
251
252    BKNI_Memset(&g_NEXUS_SurfaceModuleData, 0, sizeof(g_NEXUS_SurfaceModuleData));
253    if (pSettings) {
254        g_NEXUS_SurfaceModuleData.settings = *pSettings;
255    }
256    else {
257        NEXUS_SurfaceModule_GetDefaultSettings(&g_NEXUS_SurfaceModuleData.settings);
258    }
259
260    /* init global module handle */
261    NEXUS_Module_GetDefaultSettings(&moduleSettings);
262    moduleSettings.priority = NEXUS_ModulePriority_eHigh; /* surface interface is fast */
263    g_NEXUS_surfaceModule = NEXUS_Module_Create("surface", &moduleSettings);
264    if (!g_NEXUS_surfaceModule) {
265        return NULL;
266    }
267    return g_NEXUS_surfaceModule;
268}
269
270void NEXUS_SurfaceModule_Uninit(void)
271{
272    NEXUS_Module_Destroy(g_NEXUS_surfaceModule);
273    g_NEXUS_surfaceModule = NULL;
274}
275
276void NEXUS_Surface_GetDefaultCreateSettings(NEXUS_SurfaceCreateSettings *pCreateSettings)
277{
278    BKNI_Memset(pCreateSettings, 0, sizeof(*pCreateSettings));
279    pCreateSettings->pixelFormat = NEXUS_PixelFormat_eA8_R8_G8_B8;
280    pCreateSettings->palettePixelFormat = NEXUS_PixelFormat_eA8_R8_G8_B8;
281    pCreateSettings->width = 720;
282    pCreateSettings->height = 480;
283    pCreateSettings->alignment = 12; /* 2^12 = 4K alignment needed for RAC. see nexus_dma.h for detailed description of cache coherency requirements. */
284}
285
286static void NEXUS_Surface_P_Destroy(NEXUS_SurfaceHandle surface)
287{
288    BERR_Code rc;
289    BDBG_OBJECT_ASSERT(surface, NEXUS_Surface);
290
291    BDBG_MSG(("NEXUS_Surface_P_Destroy:%#x", (unsigned)surface));
292    /* Destroy must safely allocs because this could be called during midway during a failed Create */
293    if (surface->palette) {
294        rc=BSUR_Palette_Destroy(surface->palette);
295        if(rc!=BERR_SUCCESS) {rc=BERR_TRACE(rc);}
296    }
297    if (surface->surface) {
298        rc=BSUR_Surface_Destroy(surface->surface);
299        if(rc!=BERR_SUCCESS) {rc=BERR_TRACE(rc);}
300    }
301    if (surface->buffer && NULL == surface->createSettings.pMemory) {
302        BMEM_Free(surface->heap, surface->buffer);
303    }
304    BDBG_OBJECT_DESTROY(surface, NEXUS_Surface);
305    BKNI_Free(surface);
306}
307
308NEXUS_REFCNT_CLASS_MAKE(NEXUS_Surface, ref_cnt, NEXUS_Surface_P_Destroy);
309
310NEXUS_SurfaceHandle NEXUS_Surface_Create(const NEXUS_SurfaceCreateSettings *pCreateSettings)
311{
312    BERR_Code rc = BERR_SUCCESS;
313    BPXL_Format pixel_format;
314    NEXUS_SurfaceHandle surface;
315    void *mem_uncached;
316    unsigned min_pitch;
317    NEXUS_SurfaceCreateSettings defaultSettings;
318    BSUR_Surface_Settings surfaceSettings;
319
320    if(!pCreateSettings) {
321        NEXUS_Surface_GetDefaultCreateSettings(&defaultSettings);
322        pCreateSettings = &defaultSettings;
323    }
324    BDBG_MSG(("NEXUS_Surface_Create %ux%u, pixel: %u",
325        pCreateSettings->width, pCreateSettings->height, pCreateSettings->pixelFormat));
326
327    if (NEXUS_P_PixelFormat_ToMagnum(pCreateSettings->pixelFormat, &pixel_format)) {
328        rc = BERR_TRACE(NEXUS_NOT_SUPPORTED);
329        return NULL;
330    }
331
332    surface = BKNI_Malloc(sizeof(*surface));
333    if (!surface) {rc=BERR_TRACE(BERR_OUT_OF_SYSTEM_MEMORY); return NULL;}
334    BKNI_Memset(surface, 0, sizeof(*surface));
335    BDBG_OBJECT_SET(surface, NEXUS_Surface);
336    NEXUS_REFCNT_INIT(NEXUS_Surface, &surface->ref_cnt);
337    surface->mem.pitch = pCreateSettings->pitch;
338    surface->createSettings = *pCreateSettings;
339
340    /* if NULL, get the registered default heap. modify the stored createSettings for GetCreateSettings. */
341    surface->createSettings.heap = NEXUS_P_DefaultHeap(pCreateSettings->heap);
342    /* retain support for module-level default index, but this should not be used. */
343    if (!surface->createSettings.heap && g_NEXUS_SurfaceModuleData.settings.heapIndex < NEXUS_MAX_HEAPS) {
344        surface->createSettings.heap = g_pCoreHandles->nexusHeap[g_NEXUS_SurfaceModuleData.settings.heapIndex];
345    }
346    if (!surface->createSettings.heap) {
347        rc = BERR_TRACE(NEXUS_INVALID_PARAMETER);
348        goto error;
349    }
350    surface->heap = NEXUS_Heap_GetMemHandle(surface->createSettings.heap);
351
352    rc = BPXL_GetBytesPerNPixels(pixel_format, pCreateSettings->width, &min_pitch);
353    if (rc!=BERR_SUCCESS) {rc=BERR_TRACE(rc); goto error;}
354    if (!surface->mem.pitch) {
355        surface->mem.pitch = min_pitch;
356    }
357    else if (surface->mem.pitch < min_pitch) {
358        rc = BERR_TRACE(BERR_INVALID_PARAMETER);
359        BDBG_ERR(("specified pitch is too small"));
360        goto error;
361    }
362
363    if ( pCreateSettings->pMemory )
364    {
365        uint32_t offset;
366        offset = NEXUS_AddrToOffset(pCreateSettings->pMemory);
367        if ( 0 == offset )
368        {
369            BDBG_ERR(("Invalid pMemory address %p specified", pCreateSettings->pMemory));
370            goto error;
371        }
372        surface->buffer = NEXUS_OffsetToUncachedAddr(offset);
373        BDBG_ASSERT(surface->buffer);
374    }
375
376    if (BPXL_IS_PALETTE_FORMAT(pixel_format)) {
377        BPXL_Format palette_pixel_format;
378        void *paletteMemory = NULL; /* default to magnum-allocated */
379
380        if (pCreateSettings->pPaletteMemory) {
381            uint32_t offset;
382            offset = NEXUS_AddrToOffset(pCreateSettings->pPaletteMemory);
383            if ( 0 == offset )
384            {
385                BDBG_ERR(("Invalid pPaletteMemory address %p specified", pCreateSettings->pPaletteMemory));
386                goto error;
387            }
388            paletteMemory = NEXUS_OffsetToUncachedAddr(offset);
389            BDBG_ASSERT(paletteMemory);
390        }
391
392        if (NEXUS_P_PixelFormat_ToMagnum(pCreateSettings->palettePixelFormat, &palette_pixel_format)) {
393            rc=BERR_TRACE(NEXUS_NOT_SUPPORTED);
394            goto error;
395        }
396        surface->mem.numPaletteEntries = BPXL_NUM_PALETTE_ENTRIES(pixel_format);
397        rc = BSUR_Palette_Create(surface->heap,
398                     surface->mem.numPaletteEntries,
399                     paletteMemory,
400                     palette_pixel_format,
401                     BSUR_CONSTRAINT_ADDRESS_PIXEL_ALIGNED,
402                     &surface->palette);
403        if (rc!=BERR_SUCCESS) {rc=BERR_TRACE(rc); goto error;}
404
405        /* get user address for palette */
406        rc = BSUR_Palette_GetAddress(surface->palette, &paletteMemory);
407        if (rc!=BERR_SUCCESS) {rc=BERR_TRACE(rc); goto error;}
408
409        rc = BMEM_Heap_ConvertAddressToCached(surface->heap, paletteMemory, &paletteMemory);
410        if (rc!=BERR_SUCCESS) {rc=BERR_TRACE(rc); goto error;}
411
412        surface->mem.palette = paletteMemory;
413
414        if (!pCreateSettings->pPaletteMemory) {
415            /* default nexus-created palette to transparent and black */
416            BKNI_Memset(surface->mem.palette, 0, sizeof(surface->mem.palette[0]) * surface->mem.numPaletteEntries);
417        }
418        surface->paletteOffset = NEXUS_AddrToOffset(surface->mem.palette);
419    }
420
421    /* We always alloc the memory, not SUR. This allows us to manipulate as needed. */
422    if (NULL == surface->buffer) {
423        int sz = pCreateSettings->height * surface->mem.pitch;
424        unsigned alignment_in_bytes;
425
426        /* alignment applies to the backend of the buffer too. */
427        alignment_in_bytes = 1 << pCreateSettings->alignment;
428        if (alignment_in_bytes && (sz % alignment_in_bytes)) {
429            sz += alignment_in_bytes - (sz % alignment_in_bytes);
430        }
431        surface->buffer = BMEM_AllocAligned(surface->heap, sz, pCreateSettings->alignment, 0);
432        if (!surface->buffer) {
433            BDBG_ERR(("unable to allocate surface size=%d alignment=2^%d", sz, pCreateSettings->alignment));
434            goto error;
435        }
436        BDBG_MSG(("allocated surface mem=%p size=%d alignment=2^%d", surface->buffer, sz, pCreateSettings->alignment));
437    }
438    surface->offset = NEXUS_AddrToOffset(surface->buffer);
439
440    BSUR_Surface_GetDefaultSettings( &surfaceSettings );
441    if (pCreateSettings->bitsPerPixel) {
442        surfaceSettings.stTestFeature1Settings.bEnable = true;
443        surfaceSettings.stTestFeature1Settings.ulBitsPerPixel = pCreateSettings->bitsPerPixel;
444        surfaceSettings.stTestFeature1Settings.ulPredictionMode = 1; /* NOLEFT (1) is expected for all current usage modes due to the framebuffer size */
445    }
446    else {
447        surfaceSettings.stTestFeature1Settings.bEnable = false;
448        surfaceSettings.stTestFeature1Settings.ulBitsPerPixel = 0;
449    }
450    surface->mem.bufferSize = pCreateSettings->height*surface->mem.pitch;
451
452    rc = BSUR_Surface_Create(surface->heap,
453                 pCreateSettings->width, pCreateSettings->height,
454                 surface->mem.pitch,
455                 surface->buffer, /* never NULL */
456                 pixel_format,
457                 surface->palette,
458                 BSUR_CONSTRAINT_ADDRESS_PIXEL_ALIGNED,
459                 &surfaceSettings,
460                 &surface->surface);
461    if (rc!=BERR_SUCCESS) {rc=BERR_TRACE(rc); goto error;}
462
463    /* For surfaces allocated by Magnum, convert to cached and use that address. */
464    rc = BSUR_Surface_GetAddress(surface->surface, &mem_uncached, (uint32_t *)&surface->mem.pitch);
465    if (rc!=BERR_SUCCESS) {rc=BERR_TRACE(rc); goto error;}
466    rc = BMEM_Heap_ConvertAddressToCached(surface->heap, mem_uncached, &surface->mem.buffer);
467    if (rc!=BERR_SUCCESS) {rc=BERR_TRACE(rc); goto error;}
468
469    BDBG_MSG(("NEXUS_Surface_Create:%#x %ux%u, pixel: %u", (unsigned)surface, pCreateSettings->width, pCreateSettings->height, pCreateSettings->pixelFormat));
470    return surface;
471
472error:
473    NEXUS_Surface_P_Destroy(surface);
474    return NULL;
475}
476
477
478
479void NEXUS_Surface_Destroy(NEXUS_SurfaceHandle surface)
480{
481    BDBG_MSG(("NEXUS_Surface_Destroy:%#x", (unsigned)surface));
482    BDBG_OBJECT_ASSERT(surface, NEXUS_Surface);
483    NEXUS_REFCNT_RELEASE(NEXUS_Surface, surface);
484    return;
485}
486
487NEXUS_SurfaceHandle
488NEXUS_Surface_CreateFromMagnum_priv(BSUR_Surface_Handle magnum_surface)
489{
490    NEXUS_SurfaceHandle surface;
491    void *mem_uncached;
492    uint32_t width, height;
493    BPXL_Format format;
494    BERR_Code rc;
495
496    BDBG_ASSERT(magnum_surface);
497    NEXUS_ASSERT_MODULE();
498
499    surface = BKNI_Malloc(sizeof(*surface));
500    if (!surface) {rc=BERR_TRACE(BERR_OUT_OF_SYSTEM_MEMORY); goto err_alloc;}
501    BKNI_Memset(surface, 0, sizeof(*surface));
502    BDBG_OBJECT_SET(surface, NEXUS_Surface);
503    NEXUS_REFCNT_INIT(NEXUS_Surface, &surface->ref_cnt);
504    surface->surface = magnum_surface;
505    surface->heap = g_pCoreHandles->heap[0];
506
507    /* For surfaces allocated by Magnum, convert to cached and use that address. */
508    rc = BSUR_Surface_GetAddress(magnum_surface, &mem_uncached, (uint32_t *)&surface->mem.pitch);
509    if(rc!=BERR_SUCCESS) {rc=BERR_TRACE(rc);goto err_getaddress;}
510    rc = BMEM_Heap_ConvertAddressToCached(surface->heap, mem_uncached, &surface->mem.buffer);
511    if (rc!=BERR_SUCCESS) {rc=BERR_TRACE(rc); goto err_address;}
512    rc = BSUR_Surface_GetDimensions(magnum_surface,
513        &width,
514        &height);
515    if (rc!=BERR_SUCCESS) {rc=BERR_TRACE(rc); goto err_surface;}
516    rc = BSUR_Surface_GetFormat(magnum_surface, &format);
517    if (rc!=BERR_SUCCESS) {rc=BERR_TRACE(rc); goto err_surface;}
518    rc = BSUR_Surface_GetOffset(magnum_surface, &surface->offset);
519    if (rc!=BERR_SUCCESS) {rc=BERR_TRACE(rc); goto err_surface;}
520
521    NEXUS_Surface_GetDefaultCreateSettings(&surface->createSettings);
522    surface->mem.bufferSize = height*surface->mem.pitch;
523    surface->createSettings.width = width;
524    surface->createSettings.height = height;
525    surface->createSettings.pixelFormat = NEXUS_P_PixelFormat_FromMagnum(format);
526    return surface;
527
528err_surface:
529err_address:
530err_getaddress:
531    BKNI_Free(surface);
532err_alloc:
533    return NULL;
534}
535
536void
537NEXUS_Surface_ReleaseSurface_priv(NEXUS_SurfaceHandle surface)
538{
539    NEXUS_ASSERT_MODULE();
540    BDBG_OBJECT_DESTROY(surface, NEXUS_Surface);
541    BKNI_Free(surface);
542    return;
543}
544
545/*
546Summary:
547Frees internal resources allocated by NEXUS_Surface_CreateFromMagnum_priv
548*/
549void NEXUS_Surface_ReleaseSurface_priv(NEXUS_SurfaceHandle surface);
550
551void NEXUS_Surface_GetMemory(NEXUS_SurfaceHandle surface, NEXUS_SurfaceMemory *pMemory)
552{
553    BDBG_OBJECT_ASSERT(surface, NEXUS_Surface);
554    if ( surface->createSettings.bitsPerPixel )
555    {
556        BDBG_WRN(("This surface is not directly accessible by the CPU."));
557    }
558    *pMemory = surface->mem;
559    return;
560}
561
562
563NEXUS_Error NEXUS_Surface_SetSettings(NEXUS_SurfaceHandle surface, const NEXUS_SurfaceSettings *pSettings)
564{
565    BDBG_OBJECT_ASSERT(surface, NEXUS_Surface);
566    if (pSettings->autoFlush) {
567        /* See header file comments and SW7420-1205 for rationale for this failure. */
568        return BERR_TRACE(NEXUS_INVALID_PARAMETER);
569    }
570    surface->settings = *pSettings;
571    return 0;
572}
573
574void NEXUS_Surface_GetSettings(NEXUS_SurfaceHandle surface, NEXUS_SurfaceSettings *pSettings)
575{
576    BDBG_OBJECT_ASSERT(surface, NEXUS_Surface);
577    *pSettings = surface->settings;
578}
579
580
581BSUR_Surface_Handle NEXUS_Surface_GetSurface_priv(NEXUS_SurfaceHandle surface)
582{
583    BDBG_OBJECT_ASSERT(surface, NEXUS_Surface);
584    NEXUS_ASSERT_MODULE();
585    return surface->surface;
586}
587
588void NEXUS_Surface_GetCreateSettings(NEXUS_SurfaceHandle surface, NEXUS_SurfaceCreateSettings *pCreateSettings)
589{
590    BDBG_OBJECT_ASSERT(surface, NEXUS_Surface);
591    *pCreateSettings = surface->createSettings;
592}
593
594BSUR_Surface_Handle
595NEXUS_Surface_GetSurfaceAutoFlush_priv(NEXUS_SurfaceHandle surface)
596{
597    BDBG_OBJECT_ASSERT(surface, NEXUS_Surface);
598    NEXUS_ASSERT_MODULE();
599    return surface->surface;
600}
601
602void NEXUS_Surface_InitPlane( NEXUS_SurfaceHandle surface, BM2MC_PACKET_Plane *pPlane)
603{
604    BDBG_OBJECT_ASSERT(surface, NEXUS_Surface);
605    pPlane->address = surface->offset;
606    pPlane->pitch = surface->mem.pitch;
607    pPlane->format = surface->createSettings.pixelFormat;
608    pPlane->width = surface->createSettings.width;
609    pPlane->height = surface->createSettings.height;
610}
611
612void NEXUS_Surface_InitPlane_priv( NEXUS_SurfaceHandle surface, BM2MC_PACKET_Plane *pPlane, unsigned *pPaletteOffset)
613{
614    BDBG_OBJECT_ASSERT(surface, NEXUS_Surface);
615    pPlane->address = surface->offset;
616    pPlane->pitch = surface->mem.pitch;
617    pPlane->format = surface->createSettings.pixelFormat;
618    pPlane->width = surface->createSettings.width;
619    pPlane->height = surface->createSettings.height;
620    *pPaletteOffset = surface->paletteOffset; /* will be 0 if no palette */
621}
622
623/*********************************
624* striped surface
625**********************************/
626
627BDBG_OBJECT_ID(NEXUS_StripedSurface);
628struct NEXUS_StripedSurface
629{
630    BDBG_OBJECT(NEXUS_StripedSurface)
631    NEXUS_StripedSurfaceCreateSettings createSettings;
632};
633
634void NEXUS_StripedSurface_GetDefaultCreateSettings( NEXUS_StripedSurfaceCreateSettings *pSettings )
635{
636    BKNI_Memset(pSettings, 0, sizeof(*pSettings));
637}
638
639NEXUS_StripedSurfaceHandle NEXUS_StripedSurface_Create( const NEXUS_StripedSurfaceCreateSettings *pSettings )
640{
641    NEXUS_StripedSurfaceHandle stripedSurface;
642    stripedSurface = BKNI_Malloc(sizeof(*stripedSurface));
643    if (!stripedSurface) {
644        BERR_TRACE(NEXUS_OUT_OF_SYSTEM_MEMORY);
645        return NULL;
646    }
647    BDBG_OBJECT_SET(stripedSurface, NEXUS_StripedSurface);
648    stripedSurface->createSettings = *pSettings;
649    return stripedSurface;
650}
651
652void NEXUS_StripedSurface_Destroy( NEXUS_StripedSurfaceHandle stripedSurface )
653{
654    BDBG_OBJECT_ASSERT(stripedSurface, NEXUS_StripedSurface);
655    BDBG_OBJECT_DESTROY(stripedSurface, NEXUS_StripedSurface);
656    BKNI_Free(stripedSurface);
657}
658
659void NEXUS_StripedSurface_GetCreateSettings( NEXUS_StripedSurfaceHandle stripedSurface, NEXUS_StripedSurfaceCreateSettings *pSettings )
660{
661    BDBG_OBJECT_ASSERT(stripedSurface, NEXUS_StripedSurface);
662    *pSettings = stripedSurface->createSettings;
663}
664
665NEXUS_Error NEXUS_StripedSurface_GetStatus( NEXUS_StripedSurfaceHandle stripedSurface, NEXUS_StripedSurfaceStatus *pStatus )
666{
667    BDBG_OBJECT_ASSERT(stripedSurface, NEXUS_StripedSurface);
668    BKNI_Memset(pStatus, 0, sizeof(*pStatus));
669    pStatus->width = stripedSurface->createSettings.imageWidth;
670    pStatus->height = stripedSurface->createSettings.imageHeight;
671    return 0;
672}
673
674
Note: See TracBrowser for help on using the repository browser.