Trie* trie_Create( void ) { Trie* trie = new( Trie ); Suffix suffix; suffix._0_to_7.u_64 = 0; suffix._8_to_F.u_64 = 0; trie->order0 = context_create( suffix, 0 ); { uint i; for (i = 256; i --> 0; ) { suffix._0_to_7.u_64 = i; trie->order1[i] = context_create( suffix, /*order==*/1 ); trie->order1[i]->parent = trie->order0; ++trie->order0->kids; /* Not strictly necessary, but consistent. */ } } node_Init( &trie->least_recently_used ); trie->lru_context_count = 0; #ifdef NORMAL trie->max_lru_contexts = (PZIP_TRIE_MEGS /* == 72 */ * 1024 * 1024) / sizeof( Context ); #else /* Made constant to avoid annoying irrevant fluctuations in compression ratio: */ trie->max_lru_contexts = 1348169; #endif return trie; }
static int ping_initialize_contexts (pingobj_t *ping) /* {{{ */ { pingobj_iter_t *iter; int index; if (ping == NULL) return (EINVAL); index = 0; for (iter = ping_iterator_get (ping); iter != NULL; iter = ping_iterator_next (iter)) { ping_context_t *context; size_t buffer_size; context = context_create (); context->index = index; buffer_size = sizeof (context->host); ping_iterator_get_info (iter, PING_INFO_HOSTNAME, context->host, &buffer_size); buffer_size = sizeof (context->addr); ping_iterator_get_info (iter, PING_INFO_ADDRESS, context->addr, &buffer_size); ping_iterator_set_context (iter, (void *) context); index++; } return (0); } /* }}} int ping_initialize_contexts */
/** * Creates a connection context for multiple agent support, * see topic 8.1 of IEEE 11071-20601 documentation * * @param id context id * @param addr transport address (informative) * @return created context to handle this connection */ Context *communication_transport_connect_indication(ContextId id, const char *addr) { CommunicationPlugin *comm_plugin = communication_get_plugin(id.plugin); if (!comm_plugin) return 0; Context *ctx = context_create(id, comm_plugin->type); // thread-safe block - begin comm_plugin->thread_init(ctx); communication_lock(ctx); if (ctx != NULL) { communication_fire_evt(ctx, fsm_evt_ind_transport_connection, NULL); } if (connection_listener) connection_listener(ctx, addr); communication_unlock(ctx); // thread-safe block - end return ctx; }
/* Do not call while under the GL lock. */ static struct wined3d_context *swapchain_create_context(struct wined3d_swapchain *swapchain) { struct wined3d_context **newArray; struct wined3d_context *ctx; TRACE("Creating a new context for swapchain %p, thread %u.\n", swapchain, GetCurrentThreadId()); if (!(ctx = context_create(swapchain, swapchain->front_buffer, swapchain->ds_format))) { ERR("Failed to create a new context for the swapchain\n"); return NULL; } context_release(ctx); newArray = HeapAlloc(GetProcessHeap(), 0, sizeof(*newArray) * (swapchain->num_contexts + 1)); if(!newArray) { ERR("Out of memory when trying to allocate a new context array\n"); context_destroy(swapchain->device, ctx); return NULL; } memcpy(newArray, swapchain->context, sizeof(*newArray) * swapchain->num_contexts); HeapFree(GetProcessHeap(), 0, swapchain->context); newArray[swapchain->num_contexts] = ctx; swapchain->context = newArray; swapchain->num_contexts++; TRACE("Returning context %p\n", ctx); return ctx; }
struct wined3d_context *swapchain_create_context_for_thread(IWineD3DSwapChain *iface) { IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *) iface; #ifndef VBOX_WITH_WDDM struct wined3d_context **newArray; #endif struct wined3d_context *ctx; TRACE("Creating a new context for swapchain %p, thread %d\n", This, GetCurrentThreadId()); if (!(ctx = context_create(This, (IWineD3DSurfaceImpl *)This->frontBuffer, This->ds_format))) { ERR("Failed to create a new context for the swapchain\n"); return NULL; } context_release(ctx); #ifdef VBOX_WITH_WDDM /* no need to do anything since context gets added to the device context list within the context_create call */ #else newArray = HeapAlloc(GetProcessHeap(), 0, sizeof(*newArray) * (This->num_contexts + 1)); if(!newArray) { ERR("Out of memory when trying to allocate a new context array\n"); context_destroy(This->device, ctx); return NULL; } memcpy(newArray, This->context, sizeof(*newArray) * This->num_contexts); HeapFree(GetProcessHeap(), 0, This->context); newArray[This->num_contexts] = ctx; This->context = newArray; This->num_contexts++; #endif TRACE("Returning context %p\n", ctx); return ctx; }
CALSoundDevice::CALSoundDevice(const CSoundDeviceIdentifier& dev): CSoundDevice(0) { m_data = new _cal_devdata; m_data->b_input = false; m_data->m_ctxt = context_create(dev.stringIdentifier()); m_data->m_mixer = new CALSoundMixer(*this); }
struct sched_context *sched_manual_context_create(void) { struct sched_context *tmp; tmp = context_create(); return tmp; }
CALSoundDevice::CALSoundDevice(const CSoundDeviceIdentifier &card, const CSoundDeviceIdentifier &capdev, const CSoundFormat& fmt): CSoundDevice(0) { m_data = new _cal_devdata; m_data->b_input = true; m_data->m_ctxt = context_create(card.stringIdentifier()); m_data->m_inputstream = new CALSoundStream(*this,capdev,fmt,4); }
bool pa_available(){ if(! availability_checked){ int context_available; context_available = context_create(); context_stop(); is_available = (context_available == 0); availability_checked = true; } return is_available; }
/* open callback */ static int kplugs_open(struct inode *inode, struct file *filp) { int err = 0; if (!capable(CAP_SYS_MODULE)) { return -EPERM; } /* create a new context for this file descriptor */ err = context_create((context_t **)&filp->private_data); return err ? create_error(NULL, err) : 0; }
/* * Looks up a context in the threads table. If not present, it creates it. */ void thread_context_lookup(VALUE thread, VALUE * context) { threads_table_t *t_tbl; Data_Get_Struct(threads, threads_table_t, t_tbl); if (!st_lookup(t_tbl->tbl, thread, context) || !*context) { *context = context_create(thread); st_insert(t_tbl->tbl, thread, *context); } }
/* * When a new query is received over a UDP socket from a client, the * udp_response state machine is started. See also ev_udp_in_read(), * which is the only place from where udp_response_start() is called. * * udp_response_start() starts a new transaction. First creates a new * root context for it, and starts the forwarding of the original query. * * forwarding is performed by starting a new child request, which * if all goes well result in some resource records in our context. * * when the forwarded request finished successfully, udp_response_finish() * is responsible for interpreting it and sending a response back to the client. * */ int udp_response_start (u_char *mesg_buf, int mesg_len, struct sockaddr *sa_p, Nia *inif) { const char *fn = "udp_response_start()"; Context *cont; syslog (LOG_DEBUG, "%s: start", fn); /* create context */ cont = context_create(); if (!cont) return (response_abort (cont, -1)); cont->mesg.p = mesg_buf; cont->mesg_len = mesg_len; cont->wp = mesg_buf + mesg_len; /* just after the answer section */ cont->q_id = cont->mesg.hdr->id; cont->netifaddr = nia_copy (inif); memcpy (cont->peer, sa_p, SOCKADDR_SIZEOF(*sa_p)); if (cont->mesg.hdr->opcode == OP_QUERY) { syslog (LOG_DEBUG, "%s: OPCODE = OP_QUERY", fn); /* query-response specific variables */ cont->process = udp_response_recursive_process; cont->retry = udp_response_recursive_retry; /* do the forwarding, send request to forwarder */ switch (request_start (cont, QUERY_TCP)) { case 0: /* We got a response */ return (0); case 1: /* Something wrong with the query */ cont->mesg.hdr->rcode = RC_FMTERR; return (udp_response_finish (cont)); default: /* We failed ourselves somehow */ cont->mesg.hdr->rcode = RC_SERVERERR; return (udp_response_finish (cont)); } } else { syslog (LOG_NOTICE, "%s: OPCODE unknown(%d)", fn, cont->mesg.hdr->opcode); cont->mesg.hdr->rcode = RC_NIMP; return udp_response_finish (cont); } /* NOTREACHED */ return 0; }
int main(int argc, char** argv) { char* filename = NULL; int repl_flag=0, help_flag=0; struct option long_opts[] = { {"help", no_argument, &help_flag, 1}, {"repl", no_argument, &repl_flag, 1}, {0, 0, 0, 0} }; int cont = 1; while(cont) { int opt_index = 0; switch(getopt_long(argc, argv, "hr", long_opts, &opt_index)) { case -1: cont = 0; break; case 'r': repl_flag = 1; break; case '?': case 'h': return usage(); } } if(optind < argc) filename = argv[optind++]; if((!filename && !repl_flag) || help_flag) return usage(); context* root = context_create(); root->scope = scope_create(NULL); if(filename) run_file(filename, root); if(repl_flag) run_repl(root); context_destroy(root); return 0; }
struct sched_context *sched_context_create(void) { struct sched_context *tmp; tmp = context_create(); if (tmp) { cw_cond_init(&tmp->service, NULL); if (cw_pthread_create(&tmp->tid, NULL, service_thread, tmp)) { cw_log(LOG_ERROR, "unable to start service thread: %s\n", strerror(errno)); sched_context_destroy(tmp); tmp = NULL; } } return tmp; }
const QStringList *get_source_names(){ if(source_names == NULL){ context_create(); source_names = new QStringList(); finished = false; pa_context_get_source_info_list(context, get_source_info_list_callback, NULL); do{ pa_threaded_mainloop_lock(threaded_main_loop); pa_threaded_mainloop_wait(threaded_main_loop); qDebug("Received signal..."); }while(! finished); pa_threaded_mainloop_unlock(threaded_main_loop); context_stop(); } return source_names; }
int tcp_response_start (int sock, struct sockaddr *sa_p) { const char *fn = "tcp_response_start()"; Context *cont; syslog (LOG_DEBUG, "%s: start", fn); cont = context_create(); if (!cont) return (response_abort (cont, -1)); cont->process = tcp_response_readlen_process; cont->retry = tcp_response_readlen_retry; memcpy (cont->peer, sa_p, SOCKADDR_SIZEOF(*sa_p)); cont->conn_sock = sock; cont->timeout = TCP_SRV_TIMEOUT; if (!context_timeout_register (cont, cont->timeout) && !ev_tcp_conn_in_register (cont->conn_sock, cont)) return 0; /* SUCCESS */ return (response_abort (cont, -1)); }
void test_fsm() { // Create connection context which include the state machine ContextId cid = {1, 99}; Context *ctx = context_create(cid, MANAGER_CONTEXT); FSM *fsm = ctx->fsm; // Initialize FSM FsmTransitionRule transition_table[] = { { 0, 1, 1, &testfsm_action1 }, { 1, 2, 2, &testfsm_action2 }, { 2, 3, 0, &testfsm_action3 } }; fsm_init(fsm, 0, transition_table, sizeof(transition_table) / sizeof(struct FsmTransitionRule)); CU_ASSERT_EQUAL(fsm->transition_table_size, 3); // Process inputs fsm_process_evt(ctx, 1, NULL); CU_ASSERT_EQUAL(fsm->state, 1); fsm_process_evt(ctx, 2, NULL); CU_ASSERT_EQUAL(fsm->state, 2); fsm_process_evt(ctx, 3, NULL); CU_ASSERT_EQUAL(fsm->state, 0); fsm_set_manager_state_table(fsm); CU_ASSERT_EQUAL(fsm->state, fsm_state_disconnected); context_remove(cid); }
/* Do not call while under the GL lock. */ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, enum wined3d_surface_type surface_type, struct wined3d_device *device, struct wined3d_swapchain_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops) { const struct wined3d_adapter *adapter = device->adapter; const struct wined3d_format *format; struct wined3d_display_mode mode; BOOL displaymode_set = FALSE; RECT client_rect; HWND window; HRESULT hr; UINT i; if (desc->backbuffer_count > WINED3DPRESENT_BACK_BUFFER_MAX) { FIXME("The application requested %u back buffers, this is not supported.\n", desc->backbuffer_count); return WINED3DERR_INVALIDCALL; } if (desc->backbuffer_count > 1) { FIXME("The application requested more than one back buffer, this is not properly supported.\n" "Please configure the application to use double buffering (1 back buffer) if possible.\n"); } switch (surface_type) { case WINED3D_SURFACE_TYPE_GDI: swapchain->swapchain_ops = &swapchain_gdi_ops; break; case WINED3D_SURFACE_TYPE_OPENGL: swapchain->swapchain_ops = &swapchain_gl_ops; break; default: ERR("Invalid surface type %#x.\n", surface_type); return WINED3DERR_INVALIDCALL; } window = desc->device_window ? desc->device_window : device->create_parms.focus_window; swapchain->device = device; swapchain->parent = parent; swapchain->parent_ops = parent_ops; swapchain->ref = 1; swapchain->win_handle = window; swapchain->device_window = window; wined3d_get_adapter_display_mode(device->wined3d, adapter->ordinal, &mode); swapchain->orig_width = mode.width; swapchain->orig_height = mode.height; swapchain->orig_fmt = mode.format_id; format = wined3d_get_format(&adapter->gl_info, mode.format_id); GetClientRect(window, &client_rect); if (desc->windowed && (!desc->backbuffer_width || !desc->backbuffer_height || desc->backbuffer_format == WINED3DFMT_UNKNOWN)) { if (!desc->backbuffer_width) { desc->backbuffer_width = client_rect.right; TRACE("Updating width to %u.\n", desc->backbuffer_width); } if (!desc->backbuffer_height) { desc->backbuffer_height = client_rect.bottom; TRACE("Updating height to %u.\n", desc->backbuffer_height); } if (desc->backbuffer_format == WINED3DFMT_UNKNOWN) { desc->backbuffer_format = swapchain->orig_fmt; TRACE("Updating format to %s.\n", debug_d3dformat(swapchain->orig_fmt)); } } swapchain->desc = *desc; swapchain_update_render_to_fbo(swapchain); TRACE("Creating front buffer.\n"); hr = device->device_parent->ops->create_rendertarget(device->device_parent, parent, swapchain->desc.backbuffer_width, swapchain->desc.backbuffer_height, swapchain->desc.backbuffer_format, swapchain->desc.multisample_type, swapchain->desc.multisample_quality, TRUE /* Lockable */, &swapchain->front_buffer); if (FAILED(hr)) { WARN("Failed to create front buffer, hr %#x.\n", hr); goto err; } surface_set_container(swapchain->front_buffer, WINED3D_CONTAINER_SWAPCHAIN, swapchain); if (surface_type == WINED3D_SURFACE_TYPE_OPENGL) surface_modify_location(swapchain->front_buffer, SFLAG_INDRAWABLE, TRUE); /* MSDN says we're only allowed a single fullscreen swapchain per device, * so we should really check to see if there is a fullscreen swapchain * already. Does a single head count as full screen? */ if (!desc->windowed) { struct wined3d_display_mode mode; /* Change the display settings */ mode.width = desc->backbuffer_width; mode.height = desc->backbuffer_height; mode.format_id = desc->backbuffer_format; mode.refresh_rate = desc->refresh_rate; hr = wined3d_device_set_display_mode(device, 0, &mode); if (FAILED(hr)) { WARN("Failed to set display mode, hr %#x.\n", hr); goto err; } displaymode_set = TRUE; } if (surface_type == WINED3D_SURFACE_TYPE_OPENGL) { static const enum wined3d_format_id formats[] = { WINED3DFMT_D24_UNORM_S8_UINT, WINED3DFMT_D32_UNORM, WINED3DFMT_R24_UNORM_X8_TYPELESS, WINED3DFMT_D16_UNORM, WINED3DFMT_S1_UINT_D15_UNORM }; const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; swapchain->context = HeapAlloc(GetProcessHeap(), 0, sizeof(*swapchain->context)); if (!swapchain->context) { ERR("Failed to create the context array.\n"); hr = E_OUTOFMEMORY; goto err; } swapchain->num_contexts = 1; /* In WGL both color, depth and stencil are features of a pixel format. In case of D3D they are separate. * You are able to add a depth + stencil surface at a later stage when you need it. * In order to support this properly in WineD3D we need the ability to recreate the opengl context and * drawable when this is required. This is very tricky as we need to reapply ALL opengl states for the new * context, need torecreate shaders, textures and other resources. * * The context manager already takes care of the state problem and for the other tasks code from Reset * can be used. These changes are way to risky during the 1.0 code freeze which is taking place right now. * Likely a lot of other new bugs will be exposed. For that reason request a depth stencil surface all the * time. It can cause a slight performance hit but fixes a lot of regressions. A fixme reminds of that this * issue needs to be fixed. */ for (i = 0; i < (sizeof(formats) / sizeof(*formats)); i++) { swapchain->ds_format = wined3d_get_format(gl_info, formats[i]); swapchain->context[0] = context_create(swapchain, swapchain->front_buffer, swapchain->ds_format); if (swapchain->context[0]) break; TRACE("Depth stencil format %s is not supported, trying next format\n", debug_d3dformat(formats[i])); } if (!swapchain->context[0]) { WARN("Failed to create context.\n"); hr = WINED3DERR_NOTAVAILABLE; goto err; } if (wined3d_settings.offscreen_rendering_mode != ORM_FBO && (!desc->enable_auto_depth_stencil || swapchain->desc.auto_depth_stencil_format != swapchain->ds_format->id)) { FIXME("Add OpenGL context recreation support to context_validate_onscreen_formats\n"); } context_release(swapchain->context[0]); } if (swapchain->desc.backbuffer_count > 0) { swapchain->back_buffers = HeapAlloc(GetProcessHeap(), 0, sizeof(*swapchain->back_buffers) * swapchain->desc.backbuffer_count); if (!swapchain->back_buffers) { ERR("Failed to allocate backbuffer array memory.\n"); hr = E_OUTOFMEMORY; goto err; } for (i = 0; i < swapchain->desc.backbuffer_count; ++i) { TRACE("Creating back buffer %u.\n", i); hr = device->device_parent->ops->create_rendertarget(device->device_parent, parent, swapchain->desc.backbuffer_width, swapchain->desc.backbuffer_height, swapchain->desc.backbuffer_format, swapchain->desc.multisample_type, swapchain->desc.multisample_quality, TRUE /* Lockable */, &swapchain->back_buffers[i]); if (FAILED(hr)) { WARN("Failed to create back buffer %u, hr %#x.\n", i, hr); goto err; } surface_set_container(swapchain->back_buffers[i], WINED3D_CONTAINER_SWAPCHAIN, swapchain); } } /* Swapchains share the depth/stencil buffer, so only create a single depthstencil surface. */ if (desc->enable_auto_depth_stencil && surface_type == WINED3D_SURFACE_TYPE_OPENGL) { TRACE("Creating depth/stencil buffer.\n"); if (!device->auto_depth_stencil) { hr = device->device_parent->ops->create_depth_stencil(device->device_parent, swapchain->desc.backbuffer_width, swapchain->desc.backbuffer_height, swapchain->desc.auto_depth_stencil_format, swapchain->desc.multisample_type, swapchain->desc.multisample_quality, FALSE /* FIXME: Discard */, &device->auto_depth_stencil); if (FAILED(hr)) { WARN("Failed to create the auto depth stencil, hr %#x.\n", hr); goto err; } surface_set_container(device->auto_depth_stencil, WINED3D_CONTAINER_NONE, NULL); } } wined3d_swapchain_get_gamma_ramp(swapchain, &swapchain->orig_gamma); return WINED3D_OK; err: if (displaymode_set) { DEVMODEW devmode; ClipCursor(NULL); /* Change the display settings */ memset(&devmode, 0, sizeof(devmode)); devmode.dmSize = sizeof(devmode); devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; devmode.dmBitsPerPel = format->byte_count * CHAR_BIT; devmode.dmPelsWidth = swapchain->orig_width; devmode.dmPelsHeight = swapchain->orig_height; ChangeDisplaySettingsExW(adapter->DeviceName, &devmode, NULL, CDS_FULLSCREEN, NULL); } if (swapchain->back_buffers) { for (i = 0; i < swapchain->desc.backbuffer_count; ++i) { if (swapchain->back_buffers[i]) { surface_set_container(swapchain->back_buffers[i], WINED3D_CONTAINER_NONE, NULL); wined3d_surface_decref(swapchain->back_buffers[i]); } } HeapFree(GetProcessHeap(), 0, swapchain->back_buffers); } if (swapchain->context) { if (swapchain->context[0]) { context_release(swapchain->context[0]); context_destroy(device, swapchain->context[0]); swapchain->num_contexts = 0; } HeapFree(GetProcessHeap(), 0, swapchain->context); } if (swapchain->front_buffer) { surface_set_container(swapchain->front_buffer, WINED3D_CONTAINER_NONE, NULL); wined3d_surface_decref(swapchain->front_buffer); } return hr; }
static Context* create_kid( Context* parent, Suffix suffix ) { Context* newkid = context_create( suffix, parent->order +1 ); newkid->parent = parent; ++parent->kids; return mark_new_context_as_most_recently_used( newkid ); }
//---------------------------------------------------------------------------------------------------------------------------------- // Main function for decompressing a ROHC-packet. // Param state: pointer to decompressor // Param ibuf: pointer to incoming packet // Param isize: size of incoming packet // Param obuf: pointer to output buffer // Param osize: size of output buffer // Param ddata: struct that holds important information to pass between several functions // Return: size of decompressed packet //---------------------------------------------------------------------------------------------------------------------------------- int d_decode_header(struct sd_rohc * state, unsigned char * ibuf, int isize, unsigned char * obuf, int osize, struct sd_decode_data * ddata) { int largecid=0, size, irdynvar=0, casenew=0; struct s_profile * profile; unsigned char * walk = ibuf; if(isize < 2) return(ROHC_ERROR_NO_CONTEXT); ddata->cid = d_decode_feedback_first(state, &walk, isize); if(ddata->cid == ROHC_FEEDBACK_ONLY || ddata->cid == ROHC_ERROR_NO_CONTEXT) return(ddata->cid); if(ddata->cid > 0 && state->medium->cid_type == ROHC_SMALL_CID) ddata->addcidUsed=1; if(!ddata->addcidUsed && state->medium->cid_type == ROHC_LARGE_CID) { // check if large cids are used largecid = d_sdvalue_size(walk+1); if(largecid >0 && largecid < 3) { ddata->cid = d_sdvalue_decode(walk+1); ddata->largecidUsed=1; } else return(ROHC_ERROR_NO_CONTEXT); } if(d_is_ir(walk)) { profile = find_profile(walk[largecid+1]); if(!rohc_ir_packet_crc_ok(walk, largecid, ddata->addcidUsed, profile)) return(ROHC_ERROR_CRC); if(ddata->cid >= state->context_array_size) context_array_increase(state, ddata->cid); if(state->context[ddata->cid] && state->context[ddata->cid]->profile == profile) { ddata->active = state->context[ddata->cid]; state->context[ddata->cid] = NULL; } else { casenew=1; ddata->active = context_create(state, ddata->cid, profile); if(!ddata->active) return(ROHC_ERROR_NO_CONTEXT); } ddata->active->num_recv_ir ++; size = ddata->active->profile->decode_ir(state, ddata->active, walk+largecid+3, (isize-(walk-ibuf))-3-largecid, GET_BIT_0(walk), obuf); if(size>0) { context_free(state->context[ddata->cid]); state->context[ddata->cid] = ddata->active; return(size); } if(casenew) context_free(ddata->active); else state->context[ddata->cid] = ddata->active; return(size); } else { ddata->active = find_context(state, ddata->cid); // find context if(ddata->active && ddata->active->profile) { // context is valid ddata->active->latest_used = get_milliseconds(); if(d_is_irdyn(walk)) { ddata->active->num_recv_ir_dyn ++; profile = find_profile(walk[largecid+1]); if(profile != ddata->active->profile) { // if IR-DYN changes profile, make comp. transit to NO_CONTEXT-state state->curval = state->maxval; rohc_debugf(2,"IR-DYN changed profile, sending S-NACK.\n"); return(ROHC_ERROR_NO_CONTEXT); } if(!rohc_ir_dyn_packet_crc_ok(walk, largecid, ddata->addcidUsed, profile, ddata->active)) return(ROHC_ERROR_CRC); irdynvar += 2; } return(ddata->active->profile->decode(state, ddata->active, walk, (isize-(walk-ibuf)), (ddata->largecidUsed ? (1+largecid+irdynvar) : 1+irdynvar), obuf)); } else return(ROHC_ERROR_NO_CONTEXT); } return(ROHC_ERROR_NO_CONTEXT); }
static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3d_device *device, struct wined3d_swapchain_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops) { const struct wined3d_adapter *adapter = device->adapter; const struct wined3d_gl_info *gl_info = &adapter->gl_info; struct wined3d_resource_desc surface_desc; BOOL displaymode_set = FALSE; RECT client_rect; HWND window; HRESULT hr; UINT i; if (desc->backbuffer_count > WINED3DPRESENT_BACK_BUFFER_MAX) { FIXME("The application requested %u back buffers, this is not supported.\n", desc->backbuffer_count); return WINED3DERR_INVALIDCALL; } if (desc->backbuffer_count > 1) { FIXME("The application requested more than one back buffer, this is not properly supported.\n" "Please configure the application to use double buffering (1 back buffer) if possible.\n"); } if (device->wined3d->flags & WINED3D_NO3D) swapchain->swapchain_ops = &swapchain_gdi_ops; else swapchain->swapchain_ops = &swapchain_gl_ops; window = desc->device_window ? desc->device_window : device->create_parms.focus_window; swapchain->device = device; swapchain->parent = parent; swapchain->parent_ops = parent_ops; swapchain->ref = 1; swapchain->win_handle = window; swapchain->device_window = window; if (FAILED(hr = wined3d_get_adapter_display_mode(device->wined3d, adapter->ordinal, &swapchain->original_mode, NULL))) { ERR("Failed to get current display mode, hr %#x.\n", hr); goto err; } GetClientRect(window, &client_rect); if (desc->windowed && (!desc->backbuffer_width || !desc->backbuffer_height || desc->backbuffer_format == WINED3DFMT_UNKNOWN)) { if (!desc->backbuffer_width) { desc->backbuffer_width = client_rect.right; TRACE("Updating width to %u.\n", desc->backbuffer_width); } if (!desc->backbuffer_height) { desc->backbuffer_height = client_rect.bottom; TRACE("Updating height to %u.\n", desc->backbuffer_height); } if (desc->backbuffer_format == WINED3DFMT_UNKNOWN) { desc->backbuffer_format = swapchain->original_mode.format_id; TRACE("Updating format to %s.\n", debug_d3dformat(swapchain->original_mode.format_id)); } } swapchain->desc = *desc; swapchain_update_render_to_fbo(swapchain); swapchain_update_surface(swapchain); TRACE("Creating front buffer.\n"); surface_desc.resource_type = WINED3D_RTYPE_SURFACE; surface_desc.format = swapchain->desc.backbuffer_format; surface_desc.multisample_type = swapchain->desc.multisample_type; surface_desc.multisample_quality = swapchain->desc.multisample_quality; surface_desc.usage = 0; surface_desc.pool = WINED3D_POOL_DEFAULT; surface_desc.width = swapchain->desc.backbuffer_width; surface_desc.height = swapchain->desc.backbuffer_height; surface_desc.depth = 1; surface_desc.size = 0; if (FAILED(hr = device->device_parent->ops->create_swapchain_surface(device->device_parent, parent, &surface_desc, &swapchain->front_buffer))) { WARN("Failed to create front buffer, hr %#x.\n", hr); goto err; } surface_set_swapchain(swapchain->front_buffer, swapchain); if (!(device->wined3d->flags & WINED3D_NO3D)) { surface_validate_location(swapchain->front_buffer, WINED3D_LOCATION_DRAWABLE); surface_invalidate_location(swapchain->front_buffer, ~WINED3D_LOCATION_DRAWABLE); } /* MSDN says we're only allowed a single fullscreen swapchain per device, * so we should really check to see if there is a fullscreen swapchain * already. Does a single head count as full screen? */ if (!desc->windowed) { struct wined3d_display_mode mode; /* Change the display settings */ mode.width = desc->backbuffer_width; mode.height = desc->backbuffer_height; mode.format_id = desc->backbuffer_format; mode.refresh_rate = desc->refresh_rate; mode.scanline_ordering = WINED3D_SCANLINE_ORDERING_UNKNOWN; if (FAILED(hr = wined3d_set_adapter_display_mode(device->wined3d, adapter->ordinal, &mode))) { WARN("Failed to set display mode, hr %#x.\n", hr); goto err; } displaymode_set = TRUE; } if (!(device->wined3d->flags & WINED3D_NO3D)) { static const enum wined3d_format_id formats[] = { WINED3DFMT_D24_UNORM_S8_UINT, WINED3DFMT_D32_UNORM, WINED3DFMT_R24_UNORM_X8_TYPELESS, WINED3DFMT_D16_UNORM, WINED3DFMT_S1_UINT_D15_UNORM }; swapchain->context = HeapAlloc(GetProcessHeap(), 0, sizeof(*swapchain->context)); if (!swapchain->context) { ERR("Failed to create the context array.\n"); hr = E_OUTOFMEMORY; goto err; } swapchain->num_contexts = 1; /* In WGL both color, depth and stencil are features of a pixel format. In case of D3D they are separate. * You are able to add a depth + stencil surface at a later stage when you need it. * In order to support this properly in WineD3D we need the ability to recreate the opengl context and * drawable when this is required. This is very tricky as we need to reapply ALL opengl states for the new * context, need torecreate shaders, textures and other resources. * * The context manager already takes care of the state problem and for the other tasks code from Reset * can be used. These changes are way to risky during the 1.0 code freeze which is taking place right now. * Likely a lot of other new bugs will be exposed. For that reason request a depth stencil surface all the * time. It can cause a slight performance hit but fixes a lot of regressions. A fixme reminds of that this * issue needs to be fixed. */ for (i = 0; i < (sizeof(formats) / sizeof(*formats)); i++) { swapchain->ds_format = wined3d_get_format(gl_info, formats[i]); swapchain->context[0] = context_create(swapchain, swapchain->front_buffer, swapchain->ds_format); if (swapchain->context[0]) break; TRACE("Depth stencil format %s is not supported, trying next format\n", debug_d3dformat(formats[i])); } if (!swapchain->context[0]) { WARN("Failed to create context.\n"); hr = WINED3DERR_NOTAVAILABLE; goto err; } if (wined3d_settings.offscreen_rendering_mode != ORM_FBO && (!desc->enable_auto_depth_stencil || swapchain->desc.auto_depth_stencil_format != swapchain->ds_format->id)) { FIXME("Add OpenGL context recreation support to context_validate_onscreen_formats\n"); } context_release(swapchain->context[0]); } if (swapchain->desc.backbuffer_count > 0) { swapchain->back_buffers = HeapAlloc(GetProcessHeap(), 0, sizeof(*swapchain->back_buffers) * swapchain->desc.backbuffer_count); if (!swapchain->back_buffers) { ERR("Failed to allocate backbuffer array memory.\n"); hr = E_OUTOFMEMORY; goto err; } surface_desc.usage |= WINED3DUSAGE_RENDERTARGET; for (i = 0; i < swapchain->desc.backbuffer_count; ++i) { TRACE("Creating back buffer %u.\n", i); if (FAILED(hr = device->device_parent->ops->create_swapchain_surface(device->device_parent, parent, &surface_desc, &swapchain->back_buffers[i]))) { WARN("Failed to create back buffer %u, hr %#x.\n", i, hr); swapchain->desc.backbuffer_count = i; goto err; } surface_set_swapchain(swapchain->back_buffers[i], swapchain); } } /* Swapchains share the depth/stencil buffer, so only create a single depthstencil surface. */ if (desc->enable_auto_depth_stencil && !(device->wined3d->flags & WINED3D_NO3D)) { TRACE("Creating depth/stencil buffer.\n"); if (!device->auto_depth_stencil) { surface_desc.format = swapchain->desc.auto_depth_stencil_format; surface_desc.usage = WINED3DUSAGE_DEPTHSTENCIL; if (FAILED(hr = device->device_parent->ops->create_swapchain_surface(device->device_parent, device->device_parent, &surface_desc, &device->auto_depth_stencil))) { WARN("Failed to create the auto depth stencil, hr %#x.\n", hr); goto err; } } } wined3d_swapchain_get_gamma_ramp(swapchain, &swapchain->orig_gamma); return WINED3D_OK; err: if (displaymode_set) { if (FAILED(wined3d_set_adapter_display_mode(device->wined3d, adapter->ordinal, &swapchain->original_mode))) ERR("Failed to restore display mode.\n"); ClipCursor(NULL); } if (swapchain->back_buffers) { for (i = 0; i < swapchain->desc.backbuffer_count; ++i) { if (swapchain->back_buffers[i]) { surface_set_swapchain(swapchain->back_buffers[i], NULL); wined3d_surface_decref(swapchain->back_buffers[i]); } } HeapFree(GetProcessHeap(), 0, swapchain->back_buffers); } if (swapchain->context) { if (swapchain->context[0]) { context_release(swapchain->context[0]); context_destroy(device, swapchain->context[0]); swapchain->num_contexts = 0; } HeapFree(GetProcessHeap(), 0, swapchain->context); } if (swapchain->front_buffer) { surface_set_swapchain(swapchain->front_buffer, NULL); wined3d_surface_decref(swapchain->front_buffer); } if (swapchain->surface && !GL_EXTCALL(wglDestroySurfaceWINE(swapchain->surface))) ERR("wglDestroySurfaceWINE failed to destroy surface %p\n", swapchain->surface); return hr; }
static char get_options(lopt * opt, ImlibImage * im) { size_t handle = 0, index = 0, traverse = 0; context *ctx; if (im->key) { char *key = strdup(im->key); char *tok = strtok(key, ","); traverse = 0; while (tok) { char *value = strchr(tok, '='); if (!value) { value = tok; tok = "index"; } else { *value = '\0'; value++; } if (!strcasecmp(tok, "index")) index = str2uint(value, index); else if (!strcasecmp(tok, "context")) handle = str2uint(value, handle); else if (!strcasecmp(tok, "traverse")) traverse = str2int(value, traverse); tok = strtok(NULL, ","); } free(key); } else traverse = 1; if (!handle) { ImlibImageTag *htag = __imlib_GetTag(im, "context"); if (htag && htag->val) handle = htag->val; } if (handle) ctx = context_get(handle); else if (!(ctx = context_get_by_name(im->real_file)) && !(ctx = context_create(im->real_file))) return 0; if (!index) { ImlibImageTag *htag = __imlib_GetTag(im, "index"); if (htag && htag->val) index = htag->val; } if (index < 0 || index > id3_tag_get_numframes(ctx->tag) || (index == 0 && id3_tag_get_numframes(ctx->tag) < 1)) { if (index) fprintf(stderr, "No picture frame # %d found\n", index); context_delref(ctx); return 0; } if (!index) index = 1; opt->ctx = ctx; opt->index = index; opt->traverse = traverse; opt->cache_level = (id3_tag_get_numframes(ctx->tag) > 1 ? 1 : 0); return 1; }
HRESULT swapchain_init(IWineD3DSwapChainImpl *swapchain, WINED3DSURFTYPE surface_type, IWineD3DDeviceImpl *device, WINED3DPRESENT_PARAMETERS *present_parameters, IUnknown *parent) { const struct wined3d_adapter *adapter = device->adapter; const struct wined3d_format_desc *format_desc; BOOL displaymode_set = FALSE; WINED3DDISPLAYMODE mode; RECT client_rect; HWND window = NULL; #ifdef VBOX_WITH_WDDM IWineD3DSwapChainImpl *overridenSwapchain = NULL; HDC hDC = NULL; #endif HRESULT hr; UINT i; if (present_parameters->BackBufferCount > WINED3DPRESENT_BACK_BUFFER_MAX) { ERR("The application requested %u back buffers, this is not supported.\n", present_parameters->BackBufferCount); return WINED3DERR_INVALIDCALL; } if (present_parameters->BackBufferCount > 1) { FIXME("The application requested more than one back buffer, this is not properly supported.\n" "Please configure the application to use double buffering (1 back buffer) if possible.\n"); } switch (surface_type) { case SURFACE_GDI: swapchain->lpVtbl = &IWineGDISwapChain_Vtbl; break; case SURFACE_OPENGL: swapchain->lpVtbl = &IWineD3DSwapChain_Vtbl; break; case SURFACE_UNKNOWN: FIXME("Caller tried to create a SURFACE_UNKNOWN swapchain.\n"); return WINED3DERR_INVALIDCALL; } #ifdef VBOX_WITH_WDDM if (present_parameters->hDeviceWindow) { overridenSwapchain = swapchain_find(device, present_parameters->hDeviceWindow); if (!overridenSwapchain) { ERR("invalid window handle supplied"); return E_FAIL; } window = overridenSwapchain->win_handle; hDC = overridenSwapchain->hDC; } else { hr = VBoxExtWndCreate(present_parameters->BackBufferWidth, present_parameters->BackBufferHeight, &window, &hDC); if (FAILED(hr)) { ERR("VBoxExtWndCreate failed, hr 0x%x", hr); return hr; } } Assert(window); Assert(hDC); present_parameters->hDeviceWindow = window; #else window = present_parameters->hDeviceWindow ? present_parameters->hDeviceWindow : device->createParms.hFocusWindow; #endif swapchain->device = device; swapchain->parent = parent; swapchain->ref = 1; swapchain->win_handle = window; #ifndef VBOX_WITH_WDDM swapchain->device_window = window; #else Assert(window); swapchain->hDC = hDC; swapchain->presentRt = NULL; #endif if (!present_parameters->Windowed && window) { swapchain_setup_fullscreen_window(swapchain, present_parameters->BackBufferWidth, present_parameters->BackBufferHeight); } IWineD3D_GetAdapterDisplayMode(device->wined3d, adapter->ordinal, &mode); swapchain->orig_width = mode.Width; swapchain->orig_height = mode.Height; swapchain->orig_fmt = mode.Format; format_desc = getFormatDescEntry(mode.Format, &adapter->gl_info); #ifndef VBOX_WITH_WDDM GetClientRect(window, &client_rect); #else client_rect.left = 0; client_rect.top = 0; client_rect.right = present_parameters->BackBufferWidth; client_rect.bottom = present_parameters->BackBufferHeight; #endif if (present_parameters->Windowed && (!present_parameters->BackBufferWidth || !present_parameters->BackBufferHeight || present_parameters->BackBufferFormat == WINED3DFMT_UNKNOWN)) { if (!present_parameters->BackBufferWidth) { present_parameters->BackBufferWidth = client_rect.right; TRACE("Updating width to %u.\n", present_parameters->BackBufferWidth); } if (!present_parameters->BackBufferHeight) { present_parameters->BackBufferHeight = client_rect.bottom; TRACE("Updating height to %u.\n", present_parameters->BackBufferHeight); } if (present_parameters->BackBufferFormat == WINED3DFMT_UNKNOWN) { present_parameters->BackBufferFormat = swapchain->orig_fmt; TRACE("Updating format to %s.\n", debug_d3dformat(swapchain->orig_fmt)); } } swapchain->presentParms = *present_parameters; if (wined3d_settings.offscreen_rendering_mode == ORM_FBO && present_parameters->BackBufferCount && (present_parameters->BackBufferWidth != client_rect.right || present_parameters->BackBufferHeight != client_rect.bottom)) { TRACE("Rendering to FBO. Backbuffer %ux%u, window %ux%u.\n", present_parameters->BackBufferWidth, present_parameters->BackBufferHeight, client_rect.right, client_rect.bottom); swapchain->render_to_fbo = TRUE; } TRACE("Creating front buffer.\n"); hr = IWineD3DDeviceParent_CreateRenderTarget(device->device_parent, parent, swapchain->presentParms.BackBufferWidth, swapchain->presentParms.BackBufferHeight, swapchain->presentParms.BackBufferFormat, swapchain->presentParms.MultiSampleType, swapchain->presentParms.MultiSampleQuality, TRUE /* Lockable */, &swapchain->frontBuffer); if (FAILED(hr)) { WARN("Failed to create front buffer, hr %#x.\n", hr); goto err; } IWineD3DSurface_SetContainer(swapchain->frontBuffer, (IWineD3DBase *)swapchain); ((IWineD3DSurfaceImpl *)swapchain->frontBuffer)->Flags |= SFLAG_SWAPCHAIN; if (surface_type == SURFACE_OPENGL) { IWineD3DSurface_ModifyLocation(swapchain->frontBuffer, SFLAG_INDRAWABLE, TRUE); } /* MSDN says we're only allowed a single fullscreen swapchain per device, * so we should really check to see if there is a fullscreen swapchain * already. Does a single head count as full screen? */ if (!present_parameters->Windowed) { WINED3DDISPLAYMODE mode; /* Change the display settings */ mode.Width = present_parameters->BackBufferWidth; mode.Height = present_parameters->BackBufferHeight; mode.Format = present_parameters->BackBufferFormat; mode.RefreshRate = present_parameters->FullScreen_RefreshRateInHz; hr = IWineD3DDevice_SetDisplayMode((IWineD3DDevice *)device, 0, &mode); if (FAILED(hr)) { WARN("Failed to set display mode, hr %#x.\n", hr); goto err; } displaymode_set = TRUE; } #ifndef VBOX_WITH_WDDM swapchain->context = HeapAlloc(GetProcessHeap(), 0, sizeof(swapchain->context)); if (!swapchain->context) { ERR("Failed to create the context array.\n"); hr = E_OUTOFMEMORY; goto err; } swapchain->num_contexts = 1; #endif if (surface_type == SURFACE_OPENGL) { #ifdef VBOX_WITH_WDDM struct wined3d_context * swapchainContext; #endif const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; /* In WGL both color, depth and stencil are features of a pixel format. In case of D3D they are separate. * You are able to add a depth + stencil surface at a later stage when you need it. * In order to support this properly in WineD3D we need the ability to recreate the opengl context and * drawable when this is required. This is very tricky as we need to reapply ALL opengl states for the new * context, need torecreate shaders, textures and other resources. * * The context manager already takes care of the state problem and for the other tasks code from Reset * can be used. These changes are way to risky during the 1.0 code freeze which is taking place right now. * Likely a lot of other new bugs will be exposed. For that reason request a depth stencil surface all the * time. It can cause a slight performance hit but fixes a lot of regressions. A fixme reminds of that this * issue needs to be fixed. */ if (!present_parameters->EnableAutoDepthStencil || swapchain->presentParms.AutoDepthStencilFormat != WINED3DFMT_D24_UNORM_S8_UINT) { FIXME("Add OpenGL context recreation support to context_validate_onscreen_formats\n"); } swapchain->ds_format = getFormatDescEntry(WINED3DFMT_D24_UNORM_S8_UINT, gl_info); #ifdef VBOX_WITH_WDDM swapchainContext = context_find_create(device, swapchain, (IWineD3DSurfaceImpl *)swapchain->frontBuffer, swapchain->ds_format); if (!swapchainContext) #else swapchain->context[0] = context_create(swapchain, (IWineD3DSurfaceImpl *)swapchain->frontBuffer, swapchain->ds_format); if (!swapchain->context[0]) #endif { WARN("Failed to create context.\n"); hr = WINED3DERR_NOTAVAILABLE; goto err; } #ifdef VBOX_WITH_WDDM context_release(swapchainContext); #else context_release(swapchain->context[0]); #endif } else { #ifndef VBOX_WITH_WDDM swapchain->context[0] = NULL; #endif } if (swapchain->presentParms.BackBufferCount > 0) { swapchain->backBuffer = HeapAlloc(GetProcessHeap(), 0, sizeof(*swapchain->backBuffer) * swapchain->presentParms.BackBufferCount); if (!swapchain->backBuffer) { ERR("Failed to allocate backbuffer array memory.\n"); hr = E_OUTOFMEMORY; goto err; } for (i = 0; i < swapchain->presentParms.BackBufferCount; ++i) { TRACE("Creating back buffer %u.\n", i); hr = IWineD3DDeviceParent_CreateRenderTarget(device->device_parent, parent, swapchain->presentParms.BackBufferWidth, swapchain->presentParms.BackBufferHeight, swapchain->presentParms.BackBufferFormat, swapchain->presentParms.MultiSampleType, swapchain->presentParms.MultiSampleQuality, TRUE /* Lockable */, &swapchain->backBuffer[i]); if (FAILED(hr)) { WARN("Failed to create back buffer %u, hr %#x.\n", i, hr); goto err; } IWineD3DSurface_SetContainer(swapchain->backBuffer[i], (IWineD3DBase *)swapchain); ((IWineD3DSurfaceImpl *)swapchain->backBuffer[i])->Flags |= SFLAG_SWAPCHAIN; } } /* Swapchains share the depth/stencil buffer, so only create a single depthstencil surface. */ if (present_parameters->EnableAutoDepthStencil && surface_type == SURFACE_OPENGL) { TRACE("Creating depth/stencil buffer.\n"); if (!device->auto_depth_stencil_buffer) { hr = IWineD3DDeviceParent_CreateDepthStencilSurface(device->device_parent, parent, swapchain->presentParms.BackBufferWidth, swapchain->presentParms.BackBufferHeight, swapchain->presentParms.AutoDepthStencilFormat, swapchain->presentParms.MultiSampleType, swapchain->presentParms.MultiSampleQuality, FALSE /* FIXME: Discard */, &device->auto_depth_stencil_buffer); if (FAILED(hr)) { WARN("Failed to create the auto depth stencil, hr %#x.\n", hr); goto err; } IWineD3DSurface_SetContainer(device->auto_depth_stencil_buffer, NULL); } } IWineD3DSwapChain_GetGammaRamp((IWineD3DSwapChain *)swapchain, &swapchain->orig_gamma); #ifdef VBOX_WITH_WDDM if (overridenSwapchain) { swapchain_invalidate(overridenSwapchain); } #endif return WINED3D_OK; err: if (displaymode_set) { DEVMODEW devmode; ClipCursor(NULL); /* Change the display settings */ memset(&devmode, 0, sizeof(devmode)); devmode.dmSize = sizeof(devmode); devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; devmode.dmBitsPerPel = format_desc->byte_count * 8; devmode.dmPelsWidth = swapchain->orig_width; devmode.dmPelsHeight = swapchain->orig_height; ChangeDisplaySettingsExW(adapter->DeviceName, &devmode, NULL, CDS_FULLSCREEN, NULL); } if (swapchain->backBuffer) { for (i = 0; i < swapchain->presentParms.BackBufferCount; ++i) { if (swapchain->backBuffer[i]) IWineD3DSurface_Release(swapchain->backBuffer[i]); } HeapFree(GetProcessHeap(), 0, swapchain->backBuffer); } #ifdef VBOX_WITH_WDDM if (!device->NumberOfSwapChains) { while (device->numContexts) { context_destroy(device, device->contexts[0]); } } #else if (swapchain->context) { if (swapchain->context[0]) { context_release(swapchain->context[0]); context_destroy(device, swapchain->context[0]); swapchain->num_contexts = 0; } HeapFree(GetProcessHeap(), 0, swapchain->context); } #endif if (swapchain->frontBuffer) IWineD3DSurface_Release(swapchain->frontBuffer); #ifdef VBOX_WITH_WDDM if (!overridenSwapchain && swapchain->win_handle) { VBoxExtWndDestroy(swapchain->win_handle, swapchain->hDC); } swapchain_invalidate(swapchain); #endif return hr; }
/* the module init function */ static int __init kplugs_init(void) { int err = 0; struct device *device = NULL; memory_start(); err = context_create(&GLOBAL_CONTEXT); if (err < 0) { output_string("Couldn't create the global context.\n"); ERROR_CLEAN(create_error(NULL, err)); } err = alloc_chrdev_region(&kplugs_devno , 0, 1, DEVICE_NAME); if (err < 0) { output_string("Couldn't allocate a region.\n"); ERROR_CLEAN(create_error(NULL, err)); } kplugs_class = class_create(THIS_MODULE, DEVICE_NAME); if (NULL == kplugs_class) { output_string("Couldn't create class.\n"); ERROR_CLEAN(-ENOMEM); } kplugs_cdev = cdev_alloc(); if (NULL == kplugs_cdev) { output_string("Couldn't allocate a cdev.\n"); ERROR_CLEAN(-ENOMEM); } cdev_init(kplugs_cdev, &kplugs_ops); err = cdev_add(kplugs_cdev, kplugs_devno, 1); if (err < 0) { output_string("Couldn't add the cdev.\n"); ERROR_CLEAN(create_error(NULL, err)); } device = device_create(kplugs_class, NULL, kplugs_devno, NULL, DEVICE_NAME); if (device == NULL) { output_string("Couldn't create the device.\n"); ERROR_CLEAN(-ENOMEM); } return 0; clean: if (NULL != kplugs_cdev) { cdev_del(kplugs_cdev); } if (NULL != kplugs_class) { class_destroy(kplugs_class); } if (kplugs_devno) { unregister_chrdev_region(kplugs_devno, 1); } if (NULL != GLOBAL_CONTEXT) { context_free(GLOBAL_CONTEXT); } memory_stop(); return err; }
HRESULT swapchain_create_context_cs(struct wined3d_device *device, struct wined3d_swapchain *swapchain) { const struct wined3d_adapter *adapter = device->adapter; unsigned int i; static const enum wined3d_format_id formats[] = { WINED3DFMT_D24_UNORM_S8_UINT, WINED3DFMT_D32_UNORM, WINED3DFMT_R24_UNORM_X8_TYPELESS, WINED3DFMT_D16_UNORM, WINED3DFMT_S1_UINT_D15_UNORM }; const struct wined3d_gl_info *gl_info = &adapter->gl_info; swapchain->context = HeapAlloc(GetProcessHeap(), 0, sizeof(*swapchain->context)); if (!swapchain->context) { ERR("Failed to create the context array.\n"); return E_OUTOFMEMORY; } swapchain->num_contexts = 1; /* In WGL both color, depth and stencil are features of a pixel format. In case of D3D they are separate. * You are able to add a depth + stencil surface at a later stage when you need it. * In order to support this properly in WineD3D we need the ability to recreate the opengl context and * drawable when this is required. This is very tricky as we need to reapply ALL opengl states for the new * context, need torecreate shaders, textures and other resources. * * The context manager already takes care of the state problem and for the other tasks code from Reset * can be used. These changes are way to risky during the 1.0 code freeze which is taking place right now. * Likely a lot of other new bugs will be exposed. For that reason request a depth stencil surface all the * time. It can cause a slight performance hit but fixes a lot of regressions. A fixme reminds of that this * issue needs to be fixed. */ for (i = 0; i < (sizeof(formats) / sizeof(*formats)); i++) { swapchain->ds_format = wined3d_get_format(gl_info, formats[i]); swapchain->context[0] = context_create(swapchain, swapchain->front_buffer, swapchain->ds_format); if (swapchain->context[0]) break; TRACE("Depth stencil format %s is not supported, trying next format\n", debug_d3dformat(formats[i])); } if (!swapchain->context[0]) { WARN("Failed to create context.\n"); HeapFree(GetProcessHeap(), 0, swapchain->context); swapchain->context = NULL; return WINED3DERR_NOTAVAILABLE; } if (wined3d_settings.offscreen_rendering_mode != ORM_FBO && (!swapchain->desc.enable_auto_depth_stencil || swapchain->desc.auto_depth_stencil_format != swapchain->ds_format->id)) { FIXME("Add OpenGL context recreation support to context_validate_onscreen_formats\n"); } context_release(swapchain->context[0]); return WINED3D_OK; }