Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * This file is part of the LibreOffice project.
4 : : *
5 : : * This Source Code Form is subject to the terms of the Mozilla Public
6 : : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : : *
9 : : * This file incorporates work covered by the following license notice:
10 : : *
11 : : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : : * contributor license agreements. See the NOTICE file distributed
13 : : * with this work for additional information regarding copyright
14 : : * ownership. The ASF licenses this file to you under the Apache
15 : : * License, Version 2.0 (the "License"); you may not use this file
16 : : * except in compliance with the License. You may obtain a copy of
17 : : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : : */
19 : :
20 : :
21 : : #include <boost/mem_fn.hpp>
22 : : #include "pagemanager.hxx"
23 : :
24 : : namespace canvas
25 : : {
26 : :
27 : : //////////////////////////////////////////////////////////////////////////////////
28 : : // PageManager
29 : : //////////////////////////////////////////////////////////////////////////////////
30 : :
31 : : //////////////////////////////////////////////////////////////////////////////////
32 : : // PageManager::allocateSpace
33 : : //////////////////////////////////////////////////////////////////////////////////
34 : :
35 : 0 : FragmentSharedPtr PageManager::allocateSpace( const ::basegfx::B2ISize& rSize )
36 : : {
37 : : // we are asked to find a location for the requested size.
38 : : // first we try to satisfy the request from the
39 : : // remaining space in the existing pages.
40 : 0 : const PageContainer_t::iterator aEnd(maPages.end());
41 : 0 : PageContainer_t::iterator it(maPages.begin());
42 [ # # ]: 0 : while(it != aEnd)
43 : : {
44 [ # # ]: 0 : FragmentSharedPtr pFragment((*it)->allocateSpace(rSize));
45 [ # # ]: 0 : if(pFragment)
46 : : {
47 : : // the page created a new fragment, since we maybe want
48 : : // to consolidate sparse pages we keep a reference to
49 : : // the fragment.
50 [ # # ]: 0 : maFragments.push_back(pFragment);
51 [ # # ]: 0 : return pFragment;
52 : : }
53 : :
54 [ # # ]: 0 : ++it;
55 [ # # ]: 0 : }
56 : :
57 : : // otherwise try to create a new page and allocate space there...
58 [ # # ][ # # ]: 0 : PageSharedPtr pPage(new Page(mpRenderModule));
[ # # ]
59 [ # # ][ # # ]: 0 : if(pPage->isValid())
60 : : {
61 [ # # ]: 0 : maPages.push_back(pPage);
62 [ # # ]: 0 : FragmentSharedPtr pFragment(pPage->allocateSpace(rSize));
63 [ # # ]: 0 : if (pFragment)
64 [ # # ]: 0 : maFragments.push_back(pFragment);
65 [ # # ][ # # ]: 0 : return pFragment;
66 : : }
67 : :
68 : : // the rendermodule failed to create a new page [maybe out
69 : : // of videomemory], and all other pages could not take
70 : : // the new request. we decide to create a 'naked' fragment
71 : : // which will receive its location later.
72 [ # # ][ # # ]: 0 : FragmentSharedPtr pFragment(new PageFragment(rSize));
[ # # ]
73 [ # # ]: 0 : maFragments.push_back(pFragment);
74 [ # # ][ # # ]: 0 : return pFragment;
[ # # ]
75 : : }
76 : :
77 : : //////////////////////////////////////////////////////////////////////////////////
78 : : // PageManager::free
79 : : //////////////////////////////////////////////////////////////////////////////////
80 : :
81 : 0 : void PageManager::free( const FragmentSharedPtr& pFragment )
82 : : {
83 : : // erase the reference to the given fragment from our
84 : : // internal container.
85 : : FragmentContainer_t::iterator it(
86 : : std::remove(
87 [ # # ]: 0 : maFragments.begin(),maFragments.end(),pFragment));
88 [ # # ]: 0 : maFragments.erase(it,maFragments.end());
89 : :
90 : : // let the fragment itself know about it...
91 : : // we need to pass 'this' as argument since the fragment
92 : : // needs to pass this to the page and can't create
93 : : // shared_ptr from itself...
94 [ # # ]: 0 : pFragment->free(pFragment);
95 : 0 : }
96 : :
97 : : //////////////////////////////////////////////////////////////////////////////////
98 : : // PageManager::nakedFragment
99 : : //////////////////////////////////////////////////////////////////////////////////
100 : :
101 : 0 : void PageManager::nakedFragment( const FragmentSharedPtr& pFragment )
102 : : {
103 [ # # ]: 0 : if(maPages.empty())
104 : 0 : return;
105 : :
106 : : // okay, one last chance is left, we try all available
107 : : // pages again. maybe some other fragment was deleted
108 : : // and we can exploit the space.
109 [ # # ]: 0 : while(!(relocate(pFragment)))
110 : : {
111 : : // no way, we need to free up some space...
112 : : // TODO(F1): this is a heuristic, could
113 : : // be designed as a policy.
114 : 0 : const FragmentContainer_t::const_iterator aEnd(maFragments.end());
115 : 0 : FragmentContainer_t::const_iterator candidate(maFragments.begin());
116 [ # # ]: 0 : while(candidate != aEnd)
117 : : {
118 [ # # ][ # # ]: 0 : if(*candidate && !((*candidate)->isNaked()))
[ # # ]
119 : 0 : break;
120 : 0 : ++candidate;
121 : : }
122 : :
123 [ # # ]: 0 : if (candidate != aEnd)
124 : : {
125 : 0 : const ::basegfx::B2ISize& rSize((*candidate)->getSize());
126 : 0 : sal_uInt32 nMaxArea(rSize.getX()*rSize.getY());
127 : :
128 : 0 : FragmentContainer_t::const_iterator it(candidate);
129 [ # # ]: 0 : while(it != aEnd)
130 : : {
131 [ # # ][ # # ]: 0 : if (*it && !((*it)->isNaked()))
[ # # ]
132 : : {
133 : 0 : const ::basegfx::B2ISize& rCandidateSize((*it)->getSize());
134 : 0 : const sal_uInt32 nArea(rCandidateSize.getX()*rCandidateSize.getY());
135 [ # # ]: 0 : if(nArea > nMaxArea)
136 : : {
137 : 0 : candidate=it;
138 : 0 : nMaxArea=nArea;
139 : : }
140 : : }
141 : :
142 : 0 : ++it;
143 : : }
144 : :
145 : : // this does not erase the candidate,
146 : : // but makes it 'naked'...
147 [ # # ]: 0 : (*candidate)->free(*candidate);
148 : : }
149 : : else
150 : : break;
151 : : }
152 : : }
153 : :
154 : : //////////////////////////////////////////////////////////////////////////////////
155 : : // PageManager::relocate
156 : : //////////////////////////////////////////////////////////////////////////////////
157 : :
158 : 0 : bool PageManager::relocate( const FragmentSharedPtr& pFragment )
159 : : {
160 : : // the fragment passed as argument is assumed to
161 : : // be naked, that is it is not located on any page.
162 : : // we try all available pages again, maybe some
163 : : // other fragment was deleted and we can exploit the space.
164 : 0 : const PageContainer_t::iterator aEnd(maPages.end());
165 : 0 : PageContainer_t::iterator it(maPages.begin());
166 [ # # ]: 0 : while(it != aEnd)
167 : : {
168 : : // if the page at hand takes the fragment, we immediatelly
169 : : // call select() to pull the information from the associated
170 : : // image to the hardware surface.
171 [ # # ][ # # ]: 0 : if((*it)->nakedFragment(pFragment))
172 : : {
173 : : // dirty, since newly allocated.
174 [ # # ]: 0 : pFragment->select(true);
175 : 0 : return true;
176 : : }
177 : :
178 : 0 : ++it;
179 : : }
180 : :
181 : 0 : return false;
182 : : }
183 : :
184 : : //////////////////////////////////////////////////////////////////////////////////
185 : : // PageManager::validatePages
186 : : //////////////////////////////////////////////////////////////////////////////////
187 : :
188 : 0 : void PageManager::validatePages()
189 : : {
190 : : ::std::for_each( maPages.begin(),
191 : : maPages.end(),
192 : 0 : ::boost::mem_fn(&Page::validate));
193 : 0 : }
194 : :
195 : : //////////////////////////////////////////////////////////////////////////////////
196 : : // PageManager::getPageSize
197 : : //////////////////////////////////////////////////////////////////////////////////
198 : :
199 : 0 : ::basegfx::B2ISize PageManager::getPageSize() const
200 : : {
201 : 0 : return mpRenderModule->getPageSize();
202 : : }
203 : :
204 : : //////////////////////////////////////////////////////////////////////////////////
205 : : // PageManager::getRenderModule
206 : : //////////////////////////////////////////////////////////////////////////////////
207 : :
208 : 0 : canvas::IRenderModuleSharedPtr PageManager::getRenderModule() const
209 : : {
210 : 0 : return mpRenderModule;
211 : : }
212 : : }
213 : :
214 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|